0

使用 SQL Server 2005,我尝试基于带有子查询的 case 语句进行分组,但出现错误(“每个 GROUP BY 表达式必须包含至少一个列引用。”)。我可以很容易地解决它,但是任何人都可以解释这个错误吗?我有一个对#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

[编辑] 注意(响应评论)相关和非相关子查询:

--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
4

2 回答 2

3

首先,如果我们给出完整的错误,它应该是“每个 GROUP BY 表达式必须包含至少一个不是外部引用的列。

要理解错误,我们需要澄清“外部参考”的含义

(注意:在这种情况下,它与内部或外部连接无关)

内部和外部参考主查询及其子查询。在这种情况下,EXISTS是子查询,它是一个相关子查询,因为它有一个外部引用#header.header,它引用外部表#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

清如泥?

凯夫

于 2009-06-17T18:47:22.813 回答
0

当您需要为其分组(标题)而不是值时,您告诉它按 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
于 2009-06-17T14:35:40.963 回答