SQL 左连接 - 示例连接语句语法

蔡文姬腿堡 2021-08-27 11:03:56 浏览数 (7260)
反馈

在关系型数据库中,表之间通常以某种方式相互关联,允许它们的信息在整个数据库中仅写入一次。然后,当你需要分析数据时,你需要组合来自这些相关表的信息。

要在 SQL 中执行此操作,您可以使用JOIN语句。该LEFT JOIN语句是可用的各种JOIN语句之一。当您使用它连接两个表时,它会保留第一个表(左表)的所有行,即使第二个表上没有对应的匹配项。

您可以JOINSELECT查询中使用连接两个表table_1table_2,如下所示:

SELECT columns
FROM table_1
LEFT OUTER JOIN table_2
ON relation;
SELECT columns
FROM table_1
LEFT JOIN table_2
ON relation;

首先你写下哪些列将出现在连接表中。你可以通过在列名前加上表名来指定该列属于哪个表。如果某些列的名称(如table_1.column_1table_2.column_1)与SELECT <columns>.

然后你可以将第一个表的名称写为FROM table_1.

之后,你再将第二个表的名称写为LEFT OUTER JOIN table_2or LEFT JOIN table_2(省略OUTER关键字)。

最后,你要编写用于匹配行的关系,例如ON table_1.column_A = table_2.column_B. 通常关系是通过 id 来的,但它可以是任何列。

SQL LEFT JOIN 示例

假设你有一个书籍数据库,其中有两个表,一个是书籍,另一个是作者。为避免重复每本书的所有作者信息,该信息位于其自己的表中,并且书籍只有该author_name列。

BOOK_IDTITLEAUTHOR_NAMEPUBL_YEAR
1Uno, nessuno e centomila路易吉·皮兰德罗1926
2Il visconte dimezzato伊塔洛·卡尔维诺1952
3Le tigri di Mompracem埃米利奥·萨尔加里1900
4Il giorno della civetta莱昂纳多·夏夏1961
5A ciascuno il suo莱昂纳多·夏夏1966
6Il fu Mattia Pascial路易吉·皮兰德罗1904
7I Malavoglia
乔瓦尼·维尔加1881
AUTHOR_IDNAMEYEAR_OF_BIRTHPLACE_OF_BIRTHTRVIA
1路易吉·皮兰德罗1867阿格里真托1934年诺贝尔文学奖
2乔瓦尼·维尔加1840维齐尼1920年至1922年任意大利王国参议员
3伊塔洛·斯韦沃1861的里雅斯特真名是Aron Hector Schmitz
4切萨雷·帕韦塞1908圣斯特凡诺贝尔博null
5朱塞佩·托马西·迪·兰佩杜萨1896巴勒莫1934年至1957年任兰佩杜萨王子

我们可以根据作者的姓名连接这两个表。使用该books表作为左表,你可以编写以下代码将它们连接起来:

SELECT books.title AS book_title, books.publ_year, books.author_name, authors.year_of_birth, authors.place_of_birth
   FROM books
   LEFT JOIN authors
   ON books.author_name = authors.name
;

让我们分解一下。

在第一行中,你可以选择要在最终表格中显示的列。它也是决定某些列在结果表中是否具有不同名称的地方,使用ASlike with books.title AS book_title

第二行 ,FROM books表示要考虑的第一个表,也称为左表。

然后第三行,LEFT JOIN authors,说明要考虑的其他表。

ON books.author_name = authors.name说使用行books.author_name和匹配表authors.name

在此查询之后,您将获得如下表,其中未从作者表中获取信息的行仅显示NULL.

BOOK_NAMEPUBL_YEARAUTHOR_NAMEYEAR_OF_BIRTHPLACE_OF_YEAR
Uno, nessuno e centomila1926路易吉·皮兰德罗1867阿格里真托
Il visconte dimezzato1952伊塔洛·卡尔维诺nullnull
Le tigri di Mompracem1900埃米利奥·萨尔加里null
null
Il giorno della civetta1961莱昂纳多·夏夏null
null
A ciascuno il suo1966莱昂纳多·夏夏null
null
伊夫·马蒂亚·帕斯卡1904路易吉·皮兰德罗1867阿格里真托
我马拉沃利亚1881乔瓦尼·维尔加1840维齐尼

请注意,不在books表中的作者不在此连接表中。这是因为,正如我之前所说,只保留左表(在本例中books)中不相关的行,而不是右/第二个表中的行。

更复杂的 LEFT JOIN 示例

让我们看看另一种可以JOIN与其他 SQL 功能一起使用来进行数据分析的方法。

您可能想查看数据库中存在每位作者的图书数量。您可以使用以下查询来执行此操作:

SELECT authors.name AS author_name,
    SUM(
      CASE
        WHEN books.title LIKE '%'
          THEN 1
        ELSE 0
      END
    ) as number_of_books
  FROM authors
  LEFT JOIN books
  ON books.author_name = authors.name
  GROUP BY authors.name
  ORDER BY number_of_books DESC
;

代码分解

第 1 行:SELECT在结果表中列出所需的列。

第 2 行:​SUM​是与 GROUP BY 结合使用的聚合函数。然后将组合在一起的行的值相加。

第 3-7 行:您使用​CASE 语句​根据条件获得不同的结果。在这种情况下,如果一行包含书名,则计为 1,否则计为 0。这里我们LIKE用来检查单元格是否包含任何字符。

第 8 行:这给出了number_of_books为 SUM 创建的列的名称。

第 9 行:本例中的左/第一个表是authors

第 10 行:本例中右侧/第二个表是books

第 11 行:这将使用作者姓名连接两个表。

第 12 行:行按作者姓名分组- 该列中具有相同值的所有行将由一行表示。

第 13 行:我们使用order by使用书籍数量降序排列。

该查询将为您提供下表。请注意,在此处只能看到authors表中的作者。books表中提到的没有authors表中条目的作者在此不存在。这是books表中不相关的行没有保留这一事实的结果。

如果authors表更新为包括books表中提到的所有作者,如下所示:
AUTHOR_NAMENUMBER_OF_BOOKS
路易吉·皮兰德罗2
乔瓦尼·维尔加1
切萨雷·帕韦塞0
朱塞佩·托马西·迪·兰佩杜萨0
伊塔洛·斯韦沃0

AUTHOR_IDNAMEYEAR_OF_BIRTHPLACE_OF_BIRTHTRIVA
1路易吉·皮兰德罗1867阿格里真托1934年诺贝尔文学奖
2乔瓦尼·维尔加1840维齐尼1920年至1922年任意大利王国参议员
3伊塔洛·斯韦沃1861的里雅斯特真名是Aron Hector Schmitz
4切萨雷·帕韦塞1908圣斯特凡诺贝尔博nulll
5朱塞佩·托马西·迪·兰佩杜萨1896巴勒莫1934年至1957年任兰佩杜萨王子
6伊塔洛·卡尔维诺1923圣地亚哥·德·拉斯维加斯nulll
7埃米利奥·萨尔加里1862维罗纳nulll
8莱昂纳多·夏夏1921拉卡尔穆托nulll

那么上面查询中的表格实际上会给出所有作者的书籍数量。

AUTHOR_NAMENUMBER_OF_BOOKS
莱昂纳多·夏夏2
路易吉·皮兰德罗2
埃米利奥·萨尔加里1
乔瓦尼·维尔加1
乔瓦尼·维尔加1
切萨雷·帕韦塞0
朱塞佩·托马西·迪·兰佩杜萨0
伊塔洛·斯韦沃0

结论

在关系型数据库中,数据应该只写一次,所以我们经常会得到多个相互关联的表。​LEFT JOIN​AUTHOR_NAME当我们需要分析来自不同表的数据和连接信息时,它是一个非常有用的盟友。享受使用这个强大的工具查询您的数据库的乐趣。


SQL

0 人点赞