Domanda

Utilizzando SQL Server 2005 sto cercando di raggruppare in base a un'istruzione case con una sottoquery, ma sto ricevendo un errore (" Ogni espressione GROUP BY deve contenere almeno un riferimento di colonna. & Quot;). Posso risolverlo abbastanza facilmente, ma qualcuno può spiegare l'errore? Ho un riferimento di colonna a # 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

[modifica] Nota (in risposta al commento) sottoquery correlate e non correlate:

--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
È stato utile?

Soluzione

Per iniziare, se forniamo l'errore completo, è necessario leggere " Ogni espressione GROUP BY deve contenere almeno una colonna che non sia un riferimento esterno. "

Per capire l'errore, dobbiamo chiarire cosa si intende per "riferimento esterno"

(Nota: in questo caso non ha nulla a che fare con i join interni o esterni)

interno e esterno fanno riferimento alla query principale e alle sue subquery. In questo caso il EXISTS è la sottoquery ed è una sottoquery correlata in quanto ha un riferimento esterno di # header.header , che fa riferimento alla tabella esterna #header , mentre qualsiasi riferimento a #detail verrebbe considerato come riferimento interno.

Quindi, in sostanza, poiché CASE utilizza una sottoquery correlata che fa riferimento alla query esterna, quindi questo genera lo stato di errore, perché questo messaggio di errore appare quando si tenta di utilizzare solo espressioni in GROUP BY clausola interpretata come riferimento esterno.

Le sottoquery possono essere utilizzate in GROUP BY, ma non per le sottoquery correlate.

In modo confuso, lo stesso errore può essere generato da una query non sottomessa, più semplice come

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'

o addirittura sostituendo la costante con un @variable

Cancella come fango?

Kev

Altri suggerimenti

Stai dicendo di raggruppare per 1 o 0 quando devi assegnargli una colonna effettiva per raggruppare per (intestazione), non per valore.

Quindi, se ho capito bene, stai cercando un elenco delle intestazioni e un conteggio dei loro record di dettagli?

Potrebbe funzionare per te?

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

Con risultati come ...

header   detail_count
1       1
2       1
3       0
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top