Como sabes, podemos usar la cláusula GROUP BY para agrupar las filas de una tabla. Sin embargo, a veces podríamos desear obtener solamente una fila de cada grupo.

Veamos un ejemplo.

PRIMERA_FILA_01

Captura 1. Si haces click en la imagen la verás más grande

Como puedes ver, varias filas tienen el mismo identificador de la cabecera. No queremos obtener los totales de cada grupo, sino una fila por cada grupo, algo como:

PRIMERA_FILA_02

Captura 2. Si haces click en la imagen la verás más grande

En la Captura 2. podemos ver el resultado que queremos conseguir, ¿cómo lo logramos?

Listado 1.

SELECT
   ASI_IDENTI,
   ASI_IDECAB,
   ASI_NUMCUE,
   ASI_MONTOX
FROM
   ASIENTOSDET D1
WHERE
   NOT EXISTS (SELECT
                  ASI_IDENTI
               FROM
                  ASIENTOSDET D2
               WHERE
                  D1.ASI_IDECAB = D2.ASI_IDECAB AND
                  D1.ASI_IDENTI > D2.ASI_IDENTI)

Para que la consulta mostrada en el Listado 1. sea rápida, debemos tener un índice según la columna ASI_IDECAB y otro índice según la columna ASI_IDENTI. Si no tenemos esos índices, esta consulta será lentísima en tablas que tienen muchas filas.

Listado 2.

SELECT
   T1.ASI_IDENTI,
   T1.ASI_IDECAB,
   T2.ASI_NUMCUE,
   T2.ASI_MONTOX
FROM
   (SELECT
       MIN(ASI_IDENTI) AS ASI_IDENTI,
       ASI_IDECAB
    FROM
       ASIENTOSDET
    GROUP BY
       ASI_IDECAB
   ) T1
JOIN
   ASIENTOSDET T2
      ON T1.ASI_IDENTI = T2.ASI_IDENTI

Haciendo pruebas el autor de este blog descubrió que la solución del Listado 1. es más eficiente que la solución del Listado 2. pero que en tablas no muy grandes (menos de 1.000.000 de filas) esa diferencia es imperceptible.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21