2010-12-15 10 views
21

¿Qué estoy haciendo mal aquí? Estoy recibiendo este error:Cada expresión GROUP BY debe contener al menos una columna que no sea una referencia externa

SELECT LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), 
      PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', 
      batchinfo.datapath), 8000))-1), 
      qvalues.name, 
      qvalues.compound, 
      qvalues.rid 
FROM batchinfo JOIN qvalues ON batchinfo.rowid=qvalues.rowid 
WHERE LEN(datapath)>4 
GROUP BY 1,2,3 
HAVING rid!=MAX(rid) 

Me gustaría agrupar por la primera, segunda y tercera columnas que tienen el máximo librado.

Funciona bien sin el grupo por tener.

Respuesta

19

Para empezar, no puede hacer esto:

having rid!=MAX(rid) 

La cláusula HAVING solo puede contener elementos que son atributos de los grupos agregados.

Además, 1, 2, 3 no es válido en GROUP BY en SQL Server - Creo que solo es válido en ORDER BY.

Puede explicar por qué esto no es lo que busca:

select 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1), 
qvalues.name, 
qvalues.compound, 
MAX(qvalues.rid) 
from batchinfo join qvalues on batchinfo.rowid=qvalues.rowid 
where LEN(datapath)>4 
group by LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1), 
qvalues.name, 
qvalues.compound 
+0

si saco el tener aún recibo el mismo error –

+0

@herrow no GROUP BY liberé, ni lo rodeas en el SELECT con una función de suma como SUM, MIN, MAX etc. Todavía no estoy seguro de qué Estás tratando de salir ... –

8

No se puede agrupar por literales, solo columnas.

Usted probablemente está buscando algo como esto:

select 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1) as pathinfo, 
qvalues.name, 
qvalues.compound, 
qvalues.rid 
from batchinfo join qvalues on batchinfo.rowid=qvalues.rowid 
where LEN(datapath)>4 
group by pathinfo, qvalues.name, qvalues.compound 
having rid!=MAX(rid) 

En primer lugar, usted tiene que dar esa primera expresión un nombre de columna con as. Luego debe especificar los nombres de las columnas en el grupo por expresión.

+0

gracias por su ayuda . Solo quiero agrupar por la primera columna, la segunda columna y la tercera. ¿Cómo haría esto? –

+0

@herrow: agruparía por los nombres de la primera, segunda y tercera columnas. Sin embargo, podría ayudarnos si pudiera explicar en lenguaje natural qué se supone que debe hacer esta consulta. – DGH

+0

@dgh necesito que se agrupe por (izquierda ......) es una subcadena de una de las columnas –

0

Cuando usa GROUP BY, también necesita usar funciones agregadas para las columnas que no están dentro de su grupo por cláusula.

No sé exactamente lo que estamos tratando de hacer, pero supongo que esto funcionaría:

select 
    LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), 
    PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1), 
    qvalues.name, 
    qvalues.compound, 
    MAX(qvalues.rid) 
from 
    batchinfo join qvalues on batchinfo.rowid=qvalues.rowid 
where 
    LEN(datapath)>4 
group by 
    LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), 
    PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1), 
    qvalues.name, 
    qvalues.compound 
having 
    rid!=MAX(rid) 

Editar: Lo que estoy tratando de hacer aquí es una group by con toda campos pero rid. Si eso no es lo que quiere, lo que necesita hacer para tener una declaración SQL válida es agregar una llamada de función agregada para cada grupo eliminado por campo ...

+0

obteniendo el mismo error –

+0

Sí, eso se debe a @Femaref, dijo: tampoco puedes agrupar por literales. Editaré mi respuesta. – rsenna

+0

como puede ver por la respuesta correcta, eso no es correcto –

0

creo que no se está utilizando GROUP BY correctamente.

El objetivo de GROUP BY es organizar su tabla en secciones basadas en una determinada columna o columnas antes de realizar funciones de matemática/agregado.

Por ejemplo, en esta tabla:

Name Age Salary 
Bob  25  20000 
Sally 42  40000 
John 42  90000 

Una instrucción SELECT puede agrupar por su nombre (Bob, Sally, y John cada uno serían grupos separados), Edad (Bob sería un grupo, Sally y John sería otro), o Salario (más o menos el mismo resultado que el nombre).

Agrupar por "1" no tiene ningún sentido porque "1" no es un nombre de columna.

+0

sí en el servidor sql puedes hacer group por 1 –

+0

@herrow: Ok, tal vez GROUP BY 1 tiene un significado particular que no conozco en el servidor sql. Sin embargo, todavía creo que agrupar por nombres de columna va a ser mucho más cercano a lo que realmente quiere. – DGH

+0

cómo agrupo en la primera columna –

13

Bueno, como se dijo antes, no se puede GROUP por literales, pienso que usted está confundido porque puedes ORDER por 1, 2, 3. Al utilizar funciones como sus columnas, que necesitan agrupar por la misma expresiónAdemás, la cláusula HAVING es incorrecta, solo puedes usar lo que está en las agregaciones. En este caso, la consulta debería ser así:

SELECT 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1), 
qvalues.name, 
qvalues.compound, 
MAX(qvalues.rid) MaxRid 
FROM batchinfo join qvalues 
ON batchinfo.rowid=qvalues.rowid 
WHERE LEN(datapath)>4 
GROUP BY 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1), 
qvalues.name, 
qvalues.compound 
0

Aquí es una simple consulta para encontrar nombre de la empresa que tiene un tipo de medicina de A y hace más de 2.

SELECT CNAME 
FROM COMPANY 
WHERE CNO IN (
    SELECT CNO 
    FROM MEDICINE 
    WHERE type='A' 
    GROUP BY CNO HAVING COUNT(type) > 2 
) 
+0

Explique su respuesta para que sea útil para más usuarios y también vea https://stackoverflow.com/help/formatting para saber cómo formatear las respuestas en stackoverflow. – NOhs

Cuestiones relacionadas