jueves, 30 de junio de 2011

SQL SERVER - Excluyendo columnas del GROUP BY

distinct_sql Bueno, el título es medio confuso… pero la idea es intentar recuperar de una tabla de la bd, un conjunto de filas distintas, y que además en su contenido incluyan una fila que no ha sido evaluada en el DISTINCT.
En otras palabras:
algunas veces no queremos que se evalúen todas las columnas… por ejemplo una columna fecha… dado que siempre va a ser distinta, pues la fecha incluye minutos, segundos , milisegundos, etc y entonces siempre cada fila será distinta… por lo que lo más sabio es excluir la fecha de la evaluación del DISTINCT (en tu caso puede ser otro campo, no necesariamente la fecha).
Recordatorio:
Como sabemos el DISTINCT se aplica  a toda la fila… y no a sólo algunas columnas, osea, esto no funciona:
SELECT DISTINCT(columna1), columna2, columna3
Si funcionara sería maravilloso.
Y entonces Uds me preguntan:
Y cómo logramos excluir algunas columnas del DISTINCT?
Ajá, para ello hacemos un truco sencillo:
1.- A la columna que no queremos evaluar la ponemos como argumento de una función SQL, por ejemplo MAX(columna1) o MIN(Columna2)
2.- Dado que estamos usando funciones de agrupamiento, tenemos que usar entonces también la cláusula GROUP BY… y como dice la teoría, en el GROUP BY van las columnas que no han sido incluídas en alguna función de agrupamiento. Ejm:
SELECT userid, documentid, MAX(RegisteredDate)
FROM Table_Document
--Opcional: WHERE userid = @userid
GROUP BY userid, documentid

--Opcional: ORDER BY MAX(RegisteredDate)
Los puntos claves aquí son la función de agrupamiento, lo cual me permite evadir la columna RegisteredDate, y el GROUP BY, el cual es necesario al usar funciones de agrupamiento.
Se habrán dado cuenta que no uso el elemento DISTINCT ... para esta solución (paradójicamente) no la necesito.
Ahora hay otro tema que hay que considerar aquí: cómo hago si las columnas que quiero incluir en mi consulta, pero al mismo tiempo quiero excluir del GROUP BY son de tipo texto? (varchar, nvarchar,,,etc)
Interesante pregunta no?
Suponiendo que tengo una columna de tipo varchar, lo que tendría que hacer es envolver la columna de esta manera: 
MAX(Cast(column2 as varchar(max))) AS Column2
Y con eso se soluciona el asunto.
Espero que les sea de utilidad ;)

5 comentarios:

Luis Jesus dijo...

IMPRESIONANTE!!

BRILLANTE!!

SIMPLEMENTE ME SALVASTE EL PELLEJO!! MUCHISIMAS GRACIAS, BUENOS APORTES, SIGAN ASI!!

pisciss dijo...

Me salvaste, mil graciassss!

Mario Gutierrez dijo...

Super rebuscada la solucion, pero sirver perfecto, gracias.

GoTiKo dijo...

Muchas gracias por esta información. A mi tb me ha servido de mucho.

Unknown dijo...

gracias brow, sirvio !!