【问题标题】:SQLite Subqueries and Inner JoinsSQLite 子查询和内连接
【发布时间】:2021-09-25 18:22:07
【问题描述】:

我在做一个 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。我得到了正确的答案,但不是正确的列表(问题要求专辑标题而不是专辑 ID)。代码如下:

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'));

我不明白我对最后一个代码做错了什么...任何帮助将不胜感激!还有,写的太多了,只是想把自己的思路表达清楚。

【问题讨论】:

  • inner join [...] on [...]

标签: sql sqlite subquery inner-join


【解决方案1】:

一些数据库(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 子句,在决定返回行之前

例如,这将返回 10509 行:

SELECT * FROM albums INNER JOIN tracks ON 1=1

on 子句始终为真

这将返回 10509 个曲目,但前提是查询在星期一运行

SELECT * FROM albums INNER JOIN tracks ON strftime('%w', 'now') = 1

ON 或 WHERE 中的内容与表中的数据没有任何关系。它只需要解析为布尔值即可

【讨论】:

  • 你可以抛出“允许你……违反 SQL 标准”。
  • 可能是 MySQL 的核心价值观之一 ;)
猜你喜欢
  • 2010-11-06
  • 2021-05-13
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
相关资源
最近更新 更多