使用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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top