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

213 阅读7分钟

在关系型数据库中,表与表之间往往有一定的关联,允许其信息在整个数据库中只写一次。然后,当你需要分析数据时,你就需要把这些相关表的信息结合起来。

要在SQL中做到这一点,你可以使用JOIN 语句。LEFT JOIN 语句是可用的各种JOIN 语句中的一种。当你使用它来连接两个表时,它会保留第一个表(左表)的所有行,即使在第二个表上没有相应的匹配。

你可以在SELECT 查询中使用JOIN 来连接两个表,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_2LEFT JOIN table_2 (省略OUTER 关键字)。

在最后,你会写上用来匹配行的关系,例如:ON table_1.column_A = table_2.column_B 。通常情况下,关系是通过id,但也可以是任何列。

SQL LEFT JOIN例子

假设你有一个图书数据库,其中有两个表,一个是图书,另一个是作者。为了避免重复每本书的作者信息,这些信息在自己的表中,而书中只有author_name 列。

book_id标题作者姓名出版年份
1一,二,三,四,五路易吉-皮兰德娄1926
2我的眼睛》(Il visconte dimezzato伊塔罗-卡尔维诺1952
3莫泊桑的老虎》(Le tigri di Mompracem埃米利奥-萨尔加里1900
4狸猫之日莱昂纳多-西亚斯奇亚1961
5对所有的人都是如此莱昂纳多-西亚斯基亚1966
6他是马蒂亚-帕斯卡尔路易吉-皮兰德娄1904
7I MalavogliaGiovanni Verga1881
作者_id姓名出生年份出生地琐事
1路易吉-皮兰德娄1867阿格里琴托1934年获诺贝尔文学奖
2乔瓦尼-维尔加1840维齐尼1920年至1922年任意大利王国参议员
3伊塔洛-斯维沃1861的里雅斯特本名阿隆-赫克托-施米茨
4切萨雷-帕维斯1908圣斯蒂法诺-贝尔博无名氏
5Giuseppe Tomasi di Lampedusa1896巴勒莫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
;

让我们把它分解一下。

在第一行,你选择在最后的表中显示哪些列。这也是决定某些列是否会在使用AS 的结果表中有一个不同的名字的地方,就像使用books.title AS book_title 一样。

第二行,FROM books ,说明哪一个是要考虑的第一个表,也叫左表。

然后第三行,LEFT JOIN authors ,说明要考虑哪一个表。

ON books.author_name = authors.name 第3行: 和 ,说的是用这两张表来匹配。books.author_name authors.name

经过这个查询,你会得到如下表格,其中没有从作者表中得到信息的行只显示NULL :

book_title出版年份作者姓名出生年月出生地
一,二,三,四,五,六1926路易吉-皮兰德娄1867阿格里琴托
视觉障碍1952伊塔罗-卡尔维诺
莫泊桑的老虎》(Le tigri di Mompracem1900埃米利奥-萨尔加里详见不适用
狸猫之日1961莱昂纳多-沙斯卡亚ǞǞǞ
对所有的人都是如此1966Leonardo SciasciaǞǞǞǞǞǞ
他是马蒂亚-帕斯卡尔1904路易吉-皮兰德娄1867阿格里琴托
I Malavoglia1881乔瓦尼-维尔加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行:这给为SUM创建的列起了一个名字:number_of_books

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

第10行:在这种情况下,右边/第二张表是books

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

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

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

该查询将给你提供以下表格。请注意,你在这里看到的只是在authors 表中出现的作者。books 表中提到的作者,如果在authors 表中没有条目,这里就不存在。这是由于没有保留books 表中不相关的行所产生的影响:

作者姓名书籍数量
路易吉-皮兰德娄2
Giovanni Verga1
Cesare Pavese0
Giuseppe Tomasi di Lampedusa0
伊塔洛-斯维沃0

如果更新authors 表,以包括books 表中提到的所有作者,像这样:

author_id姓名出生年份出生地琐事
1路易吉-皮兰德娄1867阿格里琴托1934年获诺贝尔文学奖
2乔瓦尼-维尔加1840维齐尼1920年至1922年任意大利王国参议员
3伊塔洛-斯维沃1861的里雅斯特本名阿隆-赫克托-施密茨
4切萨雷-帕维斯1908圣斯蒂法诺-贝尔博无名氏
5Giuseppe Tomasi di Lampedusa1896巴勒莫1934年至1957年担任兰佩杜萨的亲王
6伊塔罗-卡尔维诺1923圣地亚哥-德拉斯维加斯不详
7埃米利奥-萨尔加里1862维罗纳不详
8Leonardo Sciascia1921拉卡尔穆托NULL

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

作者姓名书籍数量
Leonardo Sciascia2
路易吉-皮兰德娄2
埃米利奥-萨尔加里1
Giovanni Verga1
乔瓦尼-维尔加1
Cesare Pavese0
Giuseppe Tomasi di Lampedusa0
伊塔洛-斯维沃0

结论

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