SQLite 子查询和内部连接
SQLite Subqueries and Inner Joins
我在做 SQL 的练习题,要求为艺术家“Audioslave”创建专辑名称和单价列表,并找出返回了多少条记录。
这里是题中给出的关系数据库图片:
最初,我使用内部联接来检索列表,实际上得到了正确的答案(返回了 40 条记录)。代码如下:
select a.Title, t.UnitPrice
from albums a
inner join tracks t on t.AlbumId = a.AlbumId
inner join artists ar on ar.ArtistId = a.ArtistId
where ar.Name = 'Audioslave';
虽然我完成了这个问题,但我很好奇地尝试使用嵌套子查询来解决这个问题,并尝试首先从曲目中检索 AlbumId 和 UnitPrice。我得到了正确的答案,但不是正确的列表(问题要求专辑标题而不是 AlbumId)。这是代码:
select AlbumId, UnitPrice
from tracks
where AlbumId in (
select AlbumId
from albums
where ArtistId in (
select ArtistId
from artists
where Name = 'Audioslave'));
为了解决列表的问题,我尝试结合前面的代码。但是,我得到了完全不同数量的返回记录 (10509)。
select a.Title, t.UnitPrice
from albums a
inner join tracks t
where a.AlbumId in (
select AlbumId
from albums
where ArtistId in (
select ArtistId
from artists
where Name = 'Audioslave'));
我不明白我在最后一段代码中做错了什么...任何帮助将不胜感激!另外,写多了抱歉,我只是想把我的思考过程表达清楚。
一些数据库(SQLite、MySQL、Maria,也许还有其他数据库)允许您在不指定 ON 的情况下编写 INNER JOIN,在这种情况下,它们只是将左侧的每条记录与右侧的每条记录交叉.如果有 2 张专辑和 3 首曲目,则会产生 6 行。如果专辑是 A 和 B,曲目是 1、2 和 3,则行将是所有组合:A1、A2、A3、B1、B2、B3
除非您指定 ON,否则其他数据库(Postgres、SQLServer、Oracle,也许其他)拒绝执行此操作。要获得“左侧的每一行与右侧的每一行相结合”,您必须编写 CROSS JOIN(或编写一个始终为真的 ON 的内部联接)
考虑到数据库获取左侧的所有行并将它们连接到右侧的所有行,然后对于每个行组合,评估真实性,这可能有助于您对连接期间发生的事情的心理模型ON 子句和 WHERE 子句,然后决定 return 行
例如,这将 return 10509 行:
SELECT * FROM albums INNER JOIN tracks ON 1=1
on 子句始终为真
这将 return 10509 条曲目,但前提是查询 运行 星期一
SELECT * FROM albums INNER JOIN tracks ON strftime('%w', 'now') = 1
ON 或 WHERE 中的内容与 table 中的数据没有任何关系。它只需要解析为布尔值
我在做 SQL 的练习题,要求为艺术家“Audioslave”创建专辑名称和单价列表,并找出返回了多少条记录。
这里是题中给出的关系数据库图片:
最初,我使用内部联接来检索列表,实际上得到了正确的答案(返回了 40 条记录)。代码如下:
select a.Title, t.UnitPrice
from albums a
inner join tracks t on t.AlbumId = a.AlbumId
inner join artists ar on ar.ArtistId = a.ArtistId
where ar.Name = 'Audioslave';
虽然我完成了这个问题,但我很好奇地尝试使用嵌套子查询来解决这个问题,并尝试首先从曲目中检索 AlbumId 和 UnitPrice。我得到了正确的答案,但不是正确的列表(问题要求专辑标题而不是 AlbumId)。这是代码:
select AlbumId, UnitPrice
from tracks
where AlbumId in (
select AlbumId
from albums
where ArtistId in (
select ArtistId
from artists
where Name = 'Audioslave'));
为了解决列表的问题,我尝试结合前面的代码。但是,我得到了完全不同数量的返回记录 (10509)。
select a.Title, t.UnitPrice
from albums a
inner join tracks t
where a.AlbumId in (
select AlbumId
from albums
where ArtistId in (
select ArtistId
from artists
where Name = 'Audioslave'));
我不明白我在最后一段代码中做错了什么...任何帮助将不胜感激!另外,写多了抱歉,我只是想把我的思考过程表达清楚。
一些数据库(SQLite、MySQL、Maria,也许还有其他数据库)允许您在不指定 ON 的情况下编写 INNER JOIN,在这种情况下,它们只是将左侧的每条记录与右侧的每条记录交叉.如果有 2 张专辑和 3 首曲目,则会产生 6 行。如果专辑是 A 和 B,曲目是 1、2 和 3,则行将是所有组合:A1、A2、A3、B1、B2、B3
除非您指定 ON,否则其他数据库(Postgres、SQLServer、Oracle,也许其他)拒绝执行此操作。要获得“左侧的每一行与右侧的每一行相结合”,您必须编写 CROSS JOIN(或编写一个始终为真的 ON 的内部联接)
考虑到数据库获取左侧的所有行并将它们连接到右侧的所有行,然后对于每个行组合,评估真实性,这可能有助于您对连接期间发生的事情的心理模型ON 子句和 WHERE 子句,然后决定 return 行
例如,这将 return 10509 行:
SELECT * FROM albums INNER JOIN tracks ON 1=1
on 子句始终为真
这将 return 10509 条曲目,但前提是查询 运行 星期一
SELECT * FROM albums INNER JOIN tracks ON strftime('%w', 'now') = 1
ON 或 WHERE 中的内容与 table 中的数据没有任何关系。它只需要解析为布尔值