暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

表之间的连接

原创 pg 2022-07-29
210

到目前为止,我们的查询一次只访问一张表。查询可以一次访问多个表,或者以同时处理表的多行的方式访问同一个表。一次访问多个表(或同一表的多个实例)的查询称为连接查询。它们将一个表中的行与第二个表中的行组合在一起,并使用一个表达式来指定要配对的行。例如,要返回所有天气记录以及关联城市的位置,数据库需要将表city中每一行的列与表中所有行的列进行比较,并选择这些值所在的行对匹配。[4]weathernamecities这将通过以下查询来完成:

SELECT * FROM weather JOIN city ON city = name;
城市| temp_lo | temp_hi | prcp | 日期 | 姓名 | 地点
---------------±--------±--------±-----±-----------±--------------±----------
旧金山 | 46 | 50 | 0.25 | 1994-11-27 | 旧金山 | (-194.53)
旧金山 | 43 | 57 | 0 | 1994-11-29 | 旧金山 | (-194.53)
(2 行)
观察关于结果集的两件事:

海沃德市没有结果行。这是因为海沃德的表中没有匹配的条目cities,所以连接忽略了表中不匹配的行weather。我们很快就会看到如何解决这个问题。

有两列包含城市名称。weather这是正确的,因为和表中的列列表cities是连接在一起的。但是,在实践中这是不可取的,因此您可能希望显式列出输出列而不是使用*:

选择城市、temp_lo、temp_hi、prcp、日期、位置
从天气 JOIN city ON city = name;
由于列都有不同的名称,解析器会自动找到它们属于哪个表。如果两个表中有重复的列名,您需要限定列名以显示您的意思,如:

选择 weather.city、weather.temp_lo、weather.temp_hi、
天气.prcp、天气.日期、城市.位置
FROM weather JOIN city ON weather.city = city.name;
在连接查询中限定所有列名被广泛认为是一种很好的风格,这样如果稍后将重复的列名添加到其中一个表中,查询就不会失败。

迄今为止看到的那种连接查询也可以用这种形式编写:

选择 *
从天气,城市
WHERE 城市 = 名称;
此语法早于 SQL-92 中引入的JOIN/语法。ON表只是在FROM子句中列出,比较表达式被添加到WHERE子句中。这种较旧的隐式语法和较新的显式JOIN/ON语法的结果是相同的。但是对于查询的读者来说,显式语法使其含义更容易理解:连接条件由其自己的关键字引入,而以前该条件WHERE与其他条件一起混合到子句中。

现在我们将弄清楚如何重新获取 Hayward 记录。我们希望查询做的是扫描weather表并为每一行找到匹配的cities行。如果没有找到匹配的行,我们希望用一些“空值”来代替cities表的列。这种查询称为外连接。(到目前为止,我们看到的连接是内部连接。)命令如下所示:

选择 *
FROM weather LEFT OUTER JOIN city ON weather.city = city.name;
城市| temp_lo | temp_hi | prcp | 日期 | 姓名 | 地点
---------------±--------±--------±-----±-----------±--------------±----------
海沃德 | 37 | 54 | | 1994-11-29 | |
旧金山 | 46 | 50 | 0.25 | 1994-11-27 | 旧金山 | (-194.53)
旧金山 | 43 | 57 | 0 | 1994-11-29 | 旧金山 | (-194.53)
(3 行)
此查询称为左外连接,因为连接运算符左侧提到的表将在输出中至少包含其每一行,而右侧的表将仅具有与其中某行匹配的那些行输出左表。当输出没有右表匹配的左表行时,空(null)值将替换右表列。

练习: 还有右外连接和全外连接。试着找出那些做什么。

我们还可以将一个表与自身连接起来。这称为自联接。举个例子,假设我们希望找到在其他天气记录的温度范围内的所有天气记录。所以我们需要将每一行的temp_lo和列与所有其他行的和列进行比较。我们可以使用以下查询来做到这一点:temp_hiweathertemp_lotemp_hiweather

选择 w1.city,w1.temp_lo AS 低,w1.temp_hi AS 高,
w2.city,w2.temp_lo AS 低,w2.temp_hi AS 高
从天气 w1 加入天气 w2
ON w1.temp_lo < w2.temp_lo AND w1.temp_hi > w2.temp_hi;
城市| 低 | 高 | 城市| 低 | 高的
---------------±----±-----±--------------±----±-----
旧金山 | 43 | 57 | 旧金山 | 46 | 五十
海沃德 | 37 | 54 | 旧金山 | 46 | 50
(2 行)
在这里,我们将天气表重新标记为w1并且w2能够区分连接的左侧和右侧。您还可以在其他查​​询中使用这些类型的别名来节省一些输入,例如:

选择 *
从天气 w 加入城市 c ON w.city = c.name;
你会经常遇到这种缩写风格。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论