Pregunta

Utilizando SQL Server 2005, intento agrupar en función de una declaración de caso con una subconsulta, pero obtengo un error (" Cada expresión GROUP BY debe contener al menos una referencia de columna. "). Puedo solucionarlo con bastante facilidad, pero ¿alguien puede explicar el error? Tengo una referencia de columna 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

[edit] Nota (en respuesta al comentario) subconsultas correlacionadas y no correlacionadas:

--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
¿Fue útil?

Solución

Para comenzar, si damos el error completo, debería leer " Cada expresión GROUP BY debe contener al menos una columna que no sea una referencia externa. "

Para comprender el error, necesitamos aclarar qué se entiende por 'referencia externa'

(Nota: en este caso no tiene nada que ver con uniones internas o externas)

El interno y el externo hacen referencia a la consulta principal y sus subconsultas. En este caso, el EXISTS es la subconsulta y es una correlacionada ya que tiene una referencia externa de # header.header , que hace referencia a la tabla externa #header , mientras que cualquier referencia a #detail se consideraría como referencias internas.

Entonces, en esencia, debido a que CASE utiliza una subconsulta correlacionada que hace referencia a la consulta externa, entonces esto activa el estado de error, porque este mensaje de error aparece cuando intenta usar solo expresiones en GROUP BY cláusula que se interpreta como referencias externas.

Las

subconsultas pueden utilizarse en GROUP BY, pero no las subconsultas correlacionadas.

Confusamente, el mismo error puede ser generado por una consulta no subconsultada y más simple 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'

o incluso reemplazando la constante con un @variable

¿Claro como el barro?

Kev

Otros consejos

Le está diciendo que se agrupe por 1 o 0 cuando necesita darle una columna real para agrupar por (encabezado), no por valor.

Entonces, si entiendo bien, ¿desea una lista de los encabezados y un recuento de sus registros detallados?

¿Esto puede funcionar para usted?

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 resultados como ...

header   detail_count
1       1
2       1
3       0
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top