Nelle query SQL, utilizziamo la clausola Group by per applicare funzioni aggregate.
- Ma qual è lo scopo dietro lutilizzo di un valore numerico invece del nome della colonna con la clausola Group by? Ad esempio: Raggruppa per 1.
Commenti
Risposta
Questo è effettivamente un pessimo cosa da fare IMHO, e non è supportato nella maggior parte delle altre piattaforme di database.
I motivi per cui le persone lo fanno:
- they “re lazy – Non so perché le persone pensano che la loro produttività sia migliorata scrivendo codice conciso piuttosto che digitando per altri 40 millisecondi per ottenere un codice molto più letterale.
I motivi per cui è sbagliato:
-
non si documenta da solo – qualcuno dovrà analizzare lelenco SELECT per capire il raggruppamento. In realtà sarebbe un po più chiaro in SQL Server, che non supporta cowboy che- raggruppamento sa cosa succederà come fa MySQL.
-
è fragile – qualcuno entra e cambia lelenco SELEZIONA perché gli utenti aziendali volevano un output di report diverso e ora il tuo output è un disastro. Se avessi utilizzato i nomi delle colonne in GROUP BY, lordine nellelenco SELECT sarebbe irrilevante.
SQL Server supporta ORDER BY [ordinal]; ecco alcuni argomenti paralleli contro il suo utilizzo:
Risposta
MySQL ti consente di eseguire GROUP BY
con alias ( Problemi con gli alias di colonna ). Sarebbe molto meglio che eseguire GROUP BY
con i numeri.
- Alcune persone lo insegnano ancora
- Alcuni hanno
column number
nei diagrammi SQL . Una riga dice: Ordina il risultato in base al numero di colonna specificato o a unespressione. Se lespressione è un singolo parametro, il valore viene interpretato come un numero di colonna. I numeri di colonna negativi invertono lordinamento. - Apache ha deprecato il suo utilizzo perché SQL Server ha
Google ha molti esempi di utilizzo e il motivo per cui molti hanno smesso di usarlo.
Per essere onesti, non ho usato i numeri di colonna per ORDER BY
e GROUP BY
dal 1996 (allepoca stavo facendo Oracle PL / SQL Development). Luso dei numeri di colonna è davvero per i vecchi e la compatibilità con le versioni precedenti consente a tali sviluppatori di utilizzare MySQL e altri RDBMS che permetterlo ancora.
Risposta
Considera il caso seguente:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Devi scoprire il numero di download per servizio al giorno considerando App e Applicazioni come lo stesso servizio. Raggruppando per date, services
Apps
e Applications
verranno considerati servizi separati.
In tal caso, la query sarebbe:
select date, services, sum(downloads) as downloads from test.zvijay_test group by date,services
E output:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Ma questo non è ciò che desideri poiché è necessario raggruppare applicazioni e app. Quindi cosa possiamo fare?
Un modo è sostituire Apps
con Applications
utilizzando un CASE
espressione o la funzione IF
e quindi raggruppandoli sui servizi come:
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,services
Ma questo raggruppa ancora i servizi che considerano Apps
e Applications
come servizi diversi e fornisce lo stesso output di prima:
+------------+--------------+-----------+ | 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 | +------------+--------------+-----------+
Il raggruppamento su un numero di colonna ti consente di raggruppare i dati su una colonna con alias.
select date, if(services="Apps","Applications",services) as services, sum(downloads) as downloads from test.zvijay_test group by date,2;
Dandoti così loutput desiderato come di seguito:
+------------+--------------+-----------+ | date | services | downloads | +------------+--------------+-----------+ | 2016-05-31 | Applications | 4 | | 2016-05-31 | Videos | 2 | | 2016-06-01 | Applications | 9 | | 2016-06-01 | Videos | 2 | +------------+--------------+-----------+
Io “ve ho letto molte volte che questo è un modo pigro di scrivere query o raggruppare su una colonna con alias non funziona in MySQL, ma questo è il modo di raggruppare su colonne con alias.
Questo non è il modo preferito di scrivere query, usalo solo quando è davvero necessario raggruppare su una colonna con alias.
Commenti
- ” Ma questo raggruppa ancora i servizi considerando App e Applicazioni come servizi diversi e fornisce lo stesso output del precedente “.’ non sarebbe risolto se ‘ avessi scelto un nome diverso (non in conflitto) per lalias?
- @ Daddy32 Esattamente il mio pensiero. O anche annidare ancora una volta (gruppo dopo aver selezionato)
Risposta
Non cè alcun motivo valido per usarlo. È semplicemente una scorciatoia pigra appositamente progettata per rendere difficile per uno sviluppatore con difficoltà di capire il tuo raggruppamento o ordinamento in seguito o per consentire al codice di fallire miseramente quando qualcuno cambia lordine delle colonne. Sii rispettoso dei tuoi colleghi sviluppatori e non farlo.
Rispondi
Questo ha funzionato per me. Il codice raggruppa il righe fino a 5 gruppi.
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
Il risultato sarà il seguente
Risposta
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;
Considera le query precedenti: Raggruppa per 1 significa raggruppare per la prima colonna e raggruppa per 1,2 significa raggruppare per prima e seconda colonna e raggruppare per 1,2,3 significa per raggruppare per prima seconda e terza colonna. Ad esempio:
questa immagine mostra le prime due colonne raggruppate per 1,2 cioè, non sta considerando i diversi valori di dep_date per trovare il conteggio (per calcolare il conteggio vengono prese in considerazione tutte le combinazioni distinte delle prime due colonne) mentre la seconda query risulta
immagine. Qui si considerano tutte le prime tre colonne e ci sono valori diversi per trovare il conteggio, ovvero raggruppa per tutte le prime tre colonne (per calcolare il conteggio vengono prese in considerazione tutte le combinazioni distinte delle prime tre colonne).
order by 1
solo quando sei seduto almysql>
prompt. Nel codice, utilizzaORDER BY id ASC
. Nota il caso, il nome del campo esplicito e la direzione dellordine esplicita.