Pergunta

Usando o SQL Server 2005 Estou tentando grupo baseado em uma instrução case com uma subconsulta, mas eu estou recebendo um erro ( "Cada expressão GROUP BY deve conter pelo menos uma referência de coluna. "). Eu posso trabalhar em torno dela muito facilmente, mas alguém pode explicar o erro? Eu tenho uma referência de coluna para o # 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

[editar] Nota (em resposta ao comentário) correlacionados e não correlacionados subconsultas:

--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
Foi útil?

Solução

Para começar, se dermos o erro completo, deve ler-se " Cada expressão GROUP BY deve conter pelo menos uma coluna que não é uma referência externa. "

Para entender o erro, precisamos esclarecer o que se entende por uma 'referência externa'

(Nota: neste caso não tem nada a ver com o interior ou exterior junta)

interior e exteriores são em referência à consulta principal e é subconsultas. Neste caso, o EXISTS é a subconsulta e é um correlacionada subconsulta, pois tem uma referência externa de #header.header, que faz referência a #header tabela externa, enquanto que qualquer referência a #detail seria considerado como referências internas.

Então, em essência, porque o CASE utiliza uma subconsulta correlacionada que as referências da consulta externa, então este incêndios no estado de erro, beacuse esta mensagem de erro aparece quando você tentar usar apenas expressões em uma cláusula GROUP BY que são interpretadas como referências externas .

Subqueries pode ser usado em GROUP BY, mas não correlacionados subconsultas.

Desconcertante, o mesmo erro pode ser gerado por uma consulta não-subqueried, mais simples, como

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'

ou mesmo substituir a constante com um @variable

Claro como lama?

Kev

Outras dicas

Você está dizendo a ele para grupo por 1 ou 0 quando você precisa dar-lhe uma coluna real para grupo por (cabeçalho), não o valor.

Então, se eu estou entendendo direito você está querendo uma lista dos cabeçalhos e uma contagem de seus registros de detalhes?

Isso pode funcionar para você?

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

Com resultados como ...

header   detail_count
1       1
2       1
3       0
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top