Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2011
    Messaggi
    3

    [MySQL] Group by su condizione complessa

    Il titolo non sarà chiarissimo ma non saprei come spiegarlo meglio. Questo esempio è la versione strasemplificata del mio problema:

    La tabella:

    codice:
    tabella1(valore, orario)
    Se devo estratte i dati divisi per fascia oraria, avendo il campo fascia_oraria basterebbe un "group by fascia_oraria"
    Ma la fascia dipende dai dati per i quali sto eseguendo la query, quindi ho risolto cosi:

    codice:
    select sum(valore),
    case(1) 
    	WHEN (orario>='09.00.00' and orario<'10.00.00') THEN 'fascia1'
    	WHEN (orario>='10.00.00' and orario<'11.00.00') THEN 'fascia2'
    	ELSE NULL END 
    	as fascia_oraria
    from tabella1
    where (orario>='09.00.00' and orario<'10.00.00') or (orario>='10.00.00' and orario<'11.00.00')
    group by fascia_oraria
    Dove fascia1 e fascia2 sono definiti in fase di esecuzione query. Il tutto funziona perfettamente MA non funziona se le fasce si sovrappongono! perchè ovviamente non può entrare in 2 rami del case e la select "lavora" solo una volta su ciascun valore. Questo mi crea problemi su tantissimi altri casi. Ho risolto eseguendo una query per ogni fascia oraria e unendo il tutto con una union. E tutto va bene finche la query non si complica ulteriormente e mi serve ancora creare altre unione perchè devo prendere alcuni dati su più casi che si sovrappongono e dovrei annidare troppo con le union (in alcuni casi non posso nemmeno ma lasciamo perdere).

    Aldilà di questi dettagli su i miei problemi successivi, esiste un modo più furbo per fare questa "semplice" query?

    Grazie infinite a chi ha semplicemente avuto voglia di leggere tutto

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2002
    Messaggi
    1,326
    hai provato cosi:

    codice:
    select sum(valore),
    case(1) 
    	WHEN (orario>='09.00.00' and orario<'10.00.00') THEN 'fascia1'
    	WHEN (orario>='10.00.00' and orario<'11.00.00') THEN 'fascia2'
    	ELSE NULL END 
    	as fascia_oraria
    from tabella1
    where (orario>='09.00.00' and orario<'10.00.00') or (orario>='10.00.00' and orario<'11.00.00')
    group by 
    case(1) 
    	WHEN (orario>='09.00.00' and orario<'10.00.00') THEN 'fascia1'
    	WHEN (orario>='10.00.00' and orario<'11.00.00') THEN 'fascia2'
    	ELSE  NULL  END
    ciao

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2011
    Messaggi
    3
    Grazie ma funziona in maniera identica al mio. Se non fosse chiaro il problema si presenta nel caso in cui le fasce orarie si dovrappongono. Non da errore ma i dati sono errati perchè i "valore" che appartengono a entrambe le fasce vengono sommati solo per la prima fascia che li comprende:

    codice:
    select sum(valore),
    case(1) 
    	WHEN (orario>='09.00.00' and orario<'10.30.00') THEN 'fascia1'
    	WHEN (orario>='10.00.00' and orario<'11.00.00') THEN 'fascia2'
    	ELSE NULL END 
    	as fascia_oraria
    from tabella1
    where (orario>='09.00.00' and orario<'10.30.00') or (orario>='10.00.00' and orario<'11.00.00')
    group by fascia_oraria
    Grazie comunque

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2002
    Messaggi
    1,326
    ciao,

    non avevo ben capito il problema.

    nel 'case' il field viene assegnato solo alla prima condizione valida.

    credo che tu debba creare un'ulteriore fascia e poi, successivamente, sommare i valori

    codice:
    case(1) 
    	WHEN (orario>='10.00.00' and orario<'10.30.00') THEN 'fascia0'
    	WHEN (orario>='09.00.00' and orario<'10.30.00') THEN 'fascia1'
    	WHEN (orario>='10.00.00' and orario<'11.00.00') THEN 'fascia2'
    	ELSE NULL END 
    	as fascia_oraria
    from tabella1

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2011
    Messaggi
    3
    Certo, il tuo ragionamento è corretto ma prevede di calcolare a priori le intersezioni, una cosa che non mi piace affatto. Vado a perdere tutti i vantaggi dell'uso di sql, inoltre per query eneromemente più complesse la cosa è improponibile.

    Come scrivevo prima ho temporaneamente risolto usando:

    codice:
    select sum(valore),
    case(1) 
    	WHEN (orario>='09.00.00' and orario<'10.30.00') THEN 'fascia1'
    	ELSE NULL END 
    	as fascia_oraria
    from tabella1
    where (orario>='09.00.00' and orario<'10.30.00')
    group by fascia_oraria
    union
    select sum(valore),
    case(1) 
    	WHEN (orario>='10.00.00' and orario<'11.00.00') THEN 'fascia2'
    	ELSE NULL END 
    	as fascia_oraria
    from tabella1
    where (orario>='10.00.00' and orario<'11.00.00')
    group by fascia_oraria
    Ma anche in questo modo la query si complica in maniera esagerata, nel senso che si complica la parte php che la genera e, complicando la query con molte altre condizioni che si intersecano, sarei costretto a creare una combinazione esponenziale di "union". Per ora tutto il progetto è stato fatto in questo modo, che tutto sommato regge. Ma con il complicarsi delle cose e l'aggiunta di nuove condizioni mi rendo conto che sarebbe meglio cambiare le cose. (alcune cose sono proprio impossibili finche vado avanti cosi)

    Quello che chiedo è: qualcuno saprebbe indicarmi un metodo completamente diverso per eseguire la query che ho chiesto? Un metodo che non sfrutti il "case" e che in qualche modo mi permetta di usare sql per ottenere "2 volte lo stesso risultato" tramite group by.

    Grazie

    EDIT: in questo ultimo esempio si può togliere il "case" dato che c'è una sola condizione sempre vera, ovviamente non cambia niente...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.