none
Minimo, massimo, apertura e chiusura da tabella RRS feed

  • Domanda

  • Ciao,

    Ho una tabella di un database SQLServer su cui viene registrato ogni ora un valore di peso registrato da una bilancia (colonne: ID, DataOra, Peso).

    Sto cercando, senza troppo successo, di ottenere come risultato di una Stored Procedure, i valori Massimo, Minimo, per ogni giorno; Ciò non mi risulta difficile ed ho risolto semplicemente così:

    SELECT CONVERT(Date,DataOra) AS Giorno,
            Min(W) AS Min,
            Max(W) AS Max
    FROM   MyTable
    GROUP BY CONVERT(Date,DataOra)
    ORDER BY CONVERT(Date,DataOra)                            

    Così ottengo il valore Massimo e Minimo per ogni giorno tra i ventiquattro registrati.

    Il problema sorge quando nello stesso resultset vorrei aggiungere, per ogni giorno, il valore di peso per due ore specifiche: le "00" e le "23" (di ogni giorno), cioè il peso di  inizio giornata ed il peso di fine giornata.

    Alla fine quindi il resultset presenterà cinque colonne:

    1. Data (solo giorno senza ora)
    2. Minimo (del giorno)
    3. Massimo (del giorno)
    4. Apertura (del giorno)
    5. Chiusura (del giorno)

    Che sia possibile con una unica Stored Procedure?

    E' da un po' che provo ma non tolgo un ragno dal buco...

    Vi ringrazio per la cortese risposta

    lunedì 24 agosto 2020 22:46

Risposte

  • Ciao,

    una soluzione abbastanza efficiente e che utilizza sintassi sql basilare è data da:

    ;with cte as (
    	select CONVERT(Date,DataOra) AS Giorno, DataOra, W, datepart(hour, DataOra) as hh
    	from MyTable
    )
    SELECT Giorno as Data,
            Min(W) AS Minimo,
            Max(W) AS Massimo,
    		(select W from cte as z where z.DataOra>=cte.Giorno and z.DataOra<DATEADD(day,1,cte.Giorno) and z.hh=0)as Apertura,
    		(select W from cte as z where z.DataOra>=cte.Giorno and z.DataOra<DATEADD(day,1,cte.Giorno) and z.hh=23)as Chiusura
    FROM   cte
    GROUP BY Giorno
    ORDER BY Giorno

    Si suppone che la tabella abbia indice preferibilmente clustered sul campo DataOra, viceversa la query sarebbe inefficiente.

    E' possibile valutare altre scritture conoscendo la versione Sql utilizzata, che ricordo è sempre opportuno citare nei post.

    Giorgio



    martedì 25 agosto 2020 06:39

Tutte le risposte

  • Ciao,

    una soluzione abbastanza efficiente e che utilizza sintassi sql basilare è data da:

    ;with cte as (
    	select CONVERT(Date,DataOra) AS Giorno, DataOra, W, datepart(hour, DataOra) as hh
    	from MyTable
    )
    SELECT Giorno as Data,
            Min(W) AS Minimo,
            Max(W) AS Massimo,
    		(select W from cte as z where z.DataOra>=cte.Giorno and z.DataOra<DATEADD(day,1,cte.Giorno) and z.hh=0)as Apertura,
    		(select W from cte as z where z.DataOra>=cte.Giorno and z.DataOra<DATEADD(day,1,cte.Giorno) and z.hh=23)as Chiusura
    FROM   cte
    GROUP BY Giorno
    ORDER BY Giorno

    Si suppone che la tabella abbia indice preferibilmente clustered sul campo DataOra, viceversa la query sarebbe inefficiente.

    E' possibile valutare altre scritture conoscendo la versione Sql utilizzata, che ricordo è sempre opportuno citare nei post.

    Giorgio



    martedì 25 agosto 2020 06:39
  • Grazie Giorgio... sei stato di grande aiuto.

    La frammentazione dell'indice è al 25% quindi non è cluster; provvederò a deframmentare o a modificare l'indice della tabella.

    Grazie ancora

    martedì 25 agosto 2020 08:12