使用子查询进行分组时出现SQL Server 2005错误
-
06-07-2019 - |
题
使用SQL Server 2005我试图基于带有子查询的case语句进行分组,但是我收到一个错误(“每个GROUP BY表达式必须包含至少一个列引用。 &QUOT)。我可以很容易地解决它,但任何人都可以解释错误吗?我有#header.header的列引用。
create table #header (header int)
create table #detail (header int, detail int)
insert into #header values (1)
insert into #header values (2)
insert into #header values (3)
insert into #detail values (1, 1)
insert into #detail values (2, 1)
--error: Each GROUP BY expression must contain at least one column reference.
select case when exists (select 1 from #detail where #detail.header = #header.header) then 1 else 0 end hasrecords from #header
group by case when exists (select 1 from #detail where #detail.header = #header.header) then 1 else 0 end
--results I want
select hasrecords, count(*) from
(
select case when exists (select 1 from #detail where #detail.header = #header.header) then 1 else 0 end hasrecords from #header
) hasrecords
group by hasrecords
drop table #header
drop table #detail
[edit]注意(回应评论)相关和非相关子查询:
--correlated
select header, case when exists (select 1 from #detail where #detail.header = #header.header) then 1 else 0 end hasrecords from #header
--non-correlated
select #header.header, case when count(#detail.header) > 0 then 1 else 0 end hasrecords from #header left join #detail on #header.header = #detail.header group by #header.header
解决方案
首先,如果我们给出完整错误,则应显示为“每个GROUP BY表达式必须包含至少一个不是外部引用的列。”
要理解错误,我们需要澄清'外部引用'的含义
(注意:在这种情况下,它与内部或外部连接无关)
内部和外部引用主查询及其子查询。
在这种情况下, EXISTS
是子查询,它是 相关 子查询,因为它有#header.header <的外部引用/ code>,引用外部表
#header
,而对 #detail
的任何引用都将被视为内部引用。
因此,实质上,因为 CASE
使用引用外部查询的相关子查询,然后这会触发错误状态,因为当您尝试仅使用GROUP BY中的表达式时会出现此错误消息被解释为外部引用的子句。
子查询可以在GROUP BY中使用,但不能在相关子查询中使用。
令人困惑的是,可以通过非次级的,更简单的查询生成相同的错误,例如
select
case when header=1 then 1
else 0
end headeris1,
'constant'
from #header
group by case when header=1 then 1 else 0 end , 'constant'
甚至用 @variable
清除泥土?
千电子伏
其他提示
当你需要给它一个实际的列分组(标题)而不是值时,你告诉它按1或0分组。
因此,如果我理解正确,您需要一个标题列表和详细记录计数?
这对你有用吗?
SELECT DISTINCT h.header, COUNT(d.detail) AS detail_count
FROM #header AS h
LEFT JOIN #detail AS d ON d.header = h.header
GROUP BY h.header, d.detail
结果如...
header detail_count
1 1
2 1
3 0
不隶属于 StackOverflow