Sql 是否使用嵌套的group by/having子句进行复杂联接?
我最终需要一个包含唱片集的导入记录列表 每首歌只有一首的唱片 这就是我现在使用的:Sql 是否使用嵌套的group by/having子句进行复杂联接?,sql,join,group-by,having,Sql,Join,Group By,Having,我最终需要一个包含唱片集的导入记录列表 每首歌只有一首的唱片 这就是我现在使用的: select i.id, i.created_at from imports i where i.id in ( select a.import_id from albums a inner join songs s on a.id = s.album_id group by a.id having 1 = count(s.id) ); 带有连接的嵌套select非常快速,但是外部
select i.id, i.created_at
from imports i
where i.id in (
select a.import_id
from albums a inner join songs s on a.id = s.album_id
group by a.id having 1 = count(s.id)
);
带有连接的嵌套select非常快速,但是外部
in子句的速度慢得令人痛苦
我试图使整个查询成为单个无嵌套联接,但运行了
与组/具有子句有关的问题。我所能做的就是
包含重复项的导入记录列表,这是不可接受的
有没有更优雅的方法来编写此查询?未经测试:
select
i.id, i.created_at
from
imports i
where
exists (select *
from
albums a
join
songs s on a.id = s.album_id
where
a.import_id = i.id
group by
a.id
having
count(*) = 1)
或
未经测试:
select
i.id, i.created_at
from
imports i
where
exists (select *
from
albums a
join
songs s on a.id = s.album_id
where
a.import_id = i.id
group by
a.id
having
count(*) = 1)
或
这个怎么样
SELECT i.id,
i.created_at
FROM imports i
INNER JOIN (SELECT a.import_id
FROM albums a
INNER JOIN songs s
ON a.id = s.album_id
GROUP BY a.id
HAVING Count(* ) = 1) AS TEMP
ON i.id = TEMP.import_id;
在大多数数据库系统中,连接比执行WHERE。。。这个怎么样
SELECT i.id,
i.created_at
FROM imports i
INNER JOIN (SELECT a.import_id
FROM albums a
INNER JOIN songs s
ON a.id = s.album_id
GROUP BY a.id
HAVING Count(* ) = 1) AS TEMP
ON i.id = TEMP.import_id;
SELECT i.id, i.created_at, COUNT(s.album_id)
FROM imports AS i
INNER JOIN albums AS a
ON i.id = a.import_id
INNER JOIN songs AS s
ON a.id = s.album_id
GROUP BY i.id, i.created_at
HAVING COUNT(s.album_id) = 1
在大多数数据库系统中,连接比执行WHERE。。。在
SELECT i.id, i.created_at, COUNT(s.album_id)
FROM imports AS i
INNER JOIN albums AS a
ON i.id = a.import_id
INNER JOIN songs AS s
ON a.id = s.album_id
GROUP BY i.id, i.created_at
HAVING COUNT(s.album_id) = 1
您可能不需要将计数包含在选择列表中。SQL Server不需要它,但可能会使用不同的RDBMS
您可能不需要将计数包含在选择列表中。SQL Server不需要它,但有可能是不同的RDBMS。所有三种建议的技术都应该比您的WHERE IN更快: 存在相关子查询gbn 内部联接到DA99的子查询 内部连接所有三个表 所有这些都应该起作用,所以所有这些都是+1。如果其中一个不起作用,请告诉我们
哪一个最快,取决于您的数据和执行计划。但是,这是一个有趣的例子,说明了在SQL中表达同一事物的不同方式。所有三种建议的技术都应该比WHERE in更快: 存在相关子查询gbn 内部联接到DA99的子查询 内部连接所有三个表 所有这些都应该起作用,所以所有这些都是+1。如果其中一个不起作用,请告诉我们 哪一个最快,取决于您的数据和执行计划。但这是一个有趣的例子,说明了在SQL中表达同一事物的不同方式 我试着把整个问题都解释清楚 单个无嵌套联接但遇到 群体问题/有 条款 如果使用的是SQL Server版本2005/2008,则可以使用CTE公共表表达式联接子查询 据我所知,CTE只是一个表达式,它的工作原理类似于一个虚拟视图,它只在一个select语句中工作一次—因此您将能够执行以下操作。 我通常发现使用CTE也可以提高查询性能
with AlbumSongs as (
select a.import_id
from albums a inner join songs s on a.id = s.album_id
group by a.id
having 1 = count(s.id)
)
select i.id, i.created_at
from imports i
inner join AlbumSongs A on A.import_id = i.import_id
我试着把整个问题都解释清楚
单个无嵌套联接但遇到
群体问题/有
条款
如果使用的是SQL Server版本2005/2008,则可以使用CTE公共表表达式联接子查询
据我所知,CTE只是一个表达式,它的工作原理类似于一个虚拟视图,它只在一个select语句中工作一次—因此您将能够执行以下操作。
我通常发现使用CTE也可以提高查询性能
with AlbumSongs as (
select a.import_id
from albums a inner join songs s on a.id = s.album_id
group by a.id
having 1 = count(s.id)
)
select i.id, i.created_at
from imports i
inner join AlbumSongs A on A.import_id = i.import_id
你会指定RDBMS吗?你会指定RDBMS吗?这已经足够接近了。我必须通过I.id添加组,I.created_at以实现无重复要求,请参见原始帖子。谢谢,是的,我错过了。没问题,这已经够近了。我必须通过I.id添加组,I.created_at以实现无重复要求,请参见原始帖子。谢谢,是的,我错过了。没问题。