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

  • Utilizza order by 1 solo quando sei seduto al mysql> prompt. Nel codice, utilizza ORDER BY id ASC. Nota il caso, il nome del campo esplicito e la direzione dellordine esplicita.

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.

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

inserisci qui la descrizione dellimmagine

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:

gruppo per 1,2

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 gruppo per 1,2,3

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).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *