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 中的数据没有任何关系。它只需要解析为布尔值