¿Por qué utilizamos Group by 1 y Group by 1,2,3 en la consulta SQL?


26

En las consultas SQL, utilizamos la cláusula Group by para aplicar funciones agregadas.

  • Pero, ¿cuál es el propósito de usar el valor numérico en lugar del nombre de la columna con la cláusula Group by? Por ejemplo: Agrupar por 1.

3
Úselo order by 1solo cuando esté sentado en el mysql> indicador. En código, uso ORDER BY id ASC. Tenga en cuenta el caso, el nombre de campo explícito y la dirección de pedido explícita.
dotancohen

Respuestas:


28

Esto es realmente algo malo para hacer en mi humilde opinión, y no es compatible con la mayoría de las otras plataformas de bases de datos.

Las razones por las que las personas lo hacen:

  • son vagos : no sé por qué las personas piensan que su productividad mejora al escribir código breve en lugar de escribir durante 40 milisegundos adicionales para obtener un código mucho más literal.

Las razones por las que es malo:

  • no es autodocumentado : alguien tendrá que analizar la lista SELECT para descubrir la agrupación. En realidad, sería un poco más claro en SQL Server, que no admite la agrupación de vaquero que sabe qué pasará como lo hace MySQL.

  • es frágil : alguien entra y cambia la lista SELECCIONAR porque los usuarios comerciales querían una salida de informe diferente, y ahora su salida es un desastre. Si hubiera utilizado nombres de columna en GROUP BY, el orden en la lista SELECT sería irrelevante.

SQL Server admite ORDER BY [ordinal]; Aquí hay algunos argumentos paralelos contra su uso:


9

MySQL le permite hacer GROUP BYcon alias ( Problemas con alias de columna ). Esto sería mucho mejor que hacerlo GROUP BYcon números.

Google tiene muchos ejemplos de uso y por qué muchos han dejado de usarlo.

Para ser honesto con usted, no he usado números de columna para ORDER BYy GROUP BYdesde 1996 (estaba haciendo Desarrollo de Oracle PL / SQL en ese momento). El uso de números de columna es realmente para los veteranos y la compatibilidad con versiones anteriores permite a dichos desarrolladores usar MySQL y otros RDBMS que aún lo permiten.


8

Considere el siguiente caso:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-06-01 | Apps         |         3 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Videos       |         2 |
| 2016-06-01 | Apps         |         2 |
+------------+--------------+-----------+

Debe averiguar la cantidad de descargas por servicio por día considerando las aplicaciones y aplicaciones como el mismo servicio. Agrupar por date, servicesresultaría Appsy Applicationsse consideraría servicios separados.

En ese caso, la consulta sería:

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services

Y salida:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Apps         |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Apps         |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Pero esto no es lo que desea, ya que las aplicaciones y aplicaciones que se agruparán son un requisito. Entonces, ¿qué podemos hacer?

Una forma es reemplazar Appscon el Applicationsuso de una CASEexpresión o la IFfunción y luego agruparlos por servicios como:

select 
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test 
group by date,services

Pero esto todavía agrupa los servicios considerando Appsy Applicationscomo servicios diferentes y da el mismo resultado que anteriormente:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Applications |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Agrupar sobre un número de columna le permite agrupar datos en una columna con alias.

select
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test
group by date,2;

Y, por lo tanto, le brinda la salida deseada de la siguiente manera:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

He leído muchas veces que esta es una forma perezosa de escribir consultas o agrupar sobre una columna con alias no funciona en MySQL, pero esta es la forma de agrupar sobre columnas con alias.

Esta no es la forma preferida de escribir consultas, úsela solo cuando realmente necesite agrupar sobre una columna con alias.


" Pero esto todavía agrupa los servicios considerando las aplicaciones y aplicaciones como servicios diferentes y ofrece el mismo resultado que antes ". ¿No se resolvería esto si hubiera elegido un nombre diferente (no conflictivo) para el alias?
Daddy32

3

No hay una razón válida para usarlo. Es simplemente un atajo perezoso especialmente diseñado para dificultar a algún desarrollador con problemas para descubrir su agrupación o clasificación más adelante o para permitir que el código falle miserablemente cuando alguien cambia el orden de las columnas. Sea considerado con sus compañeros desarrolladores y no lo haga.


0

Esto me funcionó. El código agrupa las filas hasta 5 grupos.

SELECT
USR.UID,
USR.PROFILENAME,
(
    CASE 
    WHEN MOD(@curRow, 5) = 0 AND @curRow > 0 THEN
        @curRow := 0
    ELSE
        @curRow := @curRow + 1 
        /*@curRow := 1*/ /*AND @curCode := USR.UID*/
    END
) AS sort_by_total  
FROM
    SS_USR_USERS USR,
    (
        SELECT
            @curRow := 0,
            @curCode := ''
    ) rt
ORDER BY
    USR.PROFILENAME,
    USR.UID

El resultado será el siguiente

ingrese la descripción de la imagen aquí


0
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2;

SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2,3;

Considere las consultas anteriores: Agrupar por 1 significa agrupar por la primera columna y agrupar por 1,2 significa agrupar por la primera y segunda columna y agrupar por 1,2,3 significa agrupar por la primera segunda y tercera columna. Por ejemplo:

agrupar por 1,2

esta imagen muestra las dos primeras columnas agrupadas por 1,2, es decir, no está considerando los diferentes valores de dep_date para encontrar el recuento (para calcular el recuento se tienen en cuenta todas las combinaciones distintas de las dos primeras columnas), mientras que la segunda consulta da como resultado agrupar por 1,2,3

imagen. Aquí está considerando las tres primeras columnas y hay diferentes valores para encontrar el recuento, es decir, está agrupando por las tres primeras columnas (para calcular el recuento se tienen en cuenta todas las combinaciones distintas de las primeras tres columnas).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.