2015-09-16 19 views
5

Sto cercando di sommare lo stato in gruppi di 24 ore per ora. Ho un ordine, stato degli ordini e tabella di stato.Somma SQL di stato diverso entro 24 ore di gruppo entro le ore

Ordinare Tabella:

+---------+-------------------------+ 
| orderid | orderdate    | 
+---------+-------------------------+ 
| 1  | 2015-09-16 00:04:19.100 | 
| 2  | 2015-09-16 00:01:19.490 | 
| 3  | 2015-09-16 00:02:33.733 | 
| 4  | 2015-09-16 00:03:58.800 | 
| 5  | 2015-09-16 00:01:16.020 | 
| 6  | 2015-09-16 00:01:16.677 | 
| 7  | 2015-09-16 00:02:06.920 | 
+---------+-------------------------+ 

Ordinare Tabella Stato: Tabella

+---------+----------+ 
| orderid | statusid | 
+---------+----------+ 
| 1  | 11  | 
| 2  | 22  | 
| 3  | 22  | 
| 4  | 11  | 
| 5  | 22  | 
| 6  | 33  | 
| 7  | 11  | 
+---------+----------+ 

Stato:

+----------+----------+ 
| statusid | status | 
+----------+----------+ 
| 11  | PVC  | 
| 22  | CCC  | 
| 33  | WWW  | 
|   |   | 
+----------+----------+ 

Sono provare a scrivere SQL che visualizzare il conteggio dello stato entro 24 ore per ordini distinti raggruppati per ora come di seguito:

+------+-----+-----+-----+ 
| Hour | PVC | CCC | WWW | 
+------+-----+-----+-----+ 
| 1 | 0 | 2 | 1 | 
| 2 | 1 | 1 | 0 | 
| 3 | 1 | 0 | 0 | 
| 4 | 1 | 0 | 0 | 
+------+-----+-----+-----+ 

Questo è il mio SQL finora. Sono bloccato cercando di ottenere la somma di ogni stato degli ordini:

SELECT 
    DATEPART(hour, o.orderdate) AS Hour, 
    SUM( 
     CASE (
      SELECT stat.status 
      FROM Status stat, orderstatus os 
      WHERE stat.status IN ('PVC') AND os.orderid = o.id AND os.statusid = stat.id 
     ) 
      WHEN 'PVC' THEN 1 
      ELSE 0 
     END 
    ) AS PVC, 
    SUM(
     CASE (
      SELECT stat.status 
      FROM Status stat, orderstatus os 
      WHERE stat.status IN ('WWW') AND os.orderid = o.id AND os.statusid = stat.id 
     ) 
      WHEN 'CCC' THEN 1 
      ELSE 0 
     END 
    ) AS CCC, 
    SUM( 
     CASE (
      SELECT stat.status 
      FROM Status stat, orderstatus os 
      WHERE stat.status IN ('CCC') AND os.orderid = o.id AND os.statusid = stat.id) 
      WHEN 'WWW' THEN 1 
      ELSE 0 
     END 
    ) AS WWW 
FROM orders o 
WHERE o.orderdate BETWEEN DATEADD(d,-1,CURRENT_TIMESTAMP) AND CURRENT_TIMESTAMP 
GROUP BY DATEPART(hour, o.orderdate) 
ORDER BY DATEPART(hour, o.orderdate); 
+0

la tabella di stato ha un errore ... ha 11 3 volte con valori diversi. – Hogan

+0

L'ho corretto. Grazie. – user1466907

risposta

0

Ecco qua - Sto ignorando gli errori nei dati poiché ciò non avrà esito positivo se la tabella di stato avesse effettivamente ID duplicati come nei dati di esempio.

SELECT hour, sum(PVC) as PVC, sum(CCC) as CCC, sum(WWW) as WWW 
from (
    select datepart(hour,orderdate) as hour, 
     case when s.status = 'PVC' then 1 else 0 end as PVC, 
     case when s.status = 'CCC' then 1 else 0 end as CCC, 
     case when s.status = 'WWW' then 1 else 0 end as WWW 
    from order o 
    join orderstatus os on o.orderid = os.orderid 
    join status s on s.statusid = os.statusid 
) sub 
group by hour 
+0

Questo ha funzionato per me. molte grazie – user1466907

0

questo dovrebbe arrivare più vicino, allora dovete pivot:

SELECT 
    DATEPART(HOUR,o.orderdate) AS orderDate_hour, 
    s.status, 
    COUNT(DISTINCT o.orderid) AS count_orderID 
FROM 
    orders o INNER JOIN 
    orderstatus os ON 
    o.orderid = os.orderid INNER JOIN 
    status s ON 
    os.statusid = s.statusid 
WHERE 
    o.orderdate >= DATEADD(d,-1,CURRENT_TIMESTAMP) 
GROUP BY 
    DATEPART(HOUR,o.orderdate) , s.status 
ORDER BY 
    DATEPART(HOUR,o.orderdate) 

provare questo per il pivot:

SELECT 
    * 
FROM 
    (SELECT 
     DATEPART(HOUR,o.orderdate) AS orderDate_hour, 
     s.status, 
     COUNT(DISTINCT o.orderid) AS count_orderID 
    FROM 
     orders o INNER JOIN 
     orderstatus os ON 
     o.orderid = os.orderid INNER JOIN 
     status s ON 
     os.statusid = s.statusid 
    WHERE 
     o.orderdate >= DATEADD(d,-1,CURRENT_TIMESTAMP) 
    GROUP BY 
     DATEPART(HOUR,o.orderdate) , s.status) s 
PIVOT (MAX(count_orderID) FOR status IN ('pvc','ccc','www')) AS p 
ORDER BY 
    orderDate_hour 
+0

Lo proverò e ti farò sapere. Grazie mille per il tuo tempo e considerazione. – user1466907

+0

sql non viene eseguito. lo stato è un nome di tabella. Intendevi avere lo stato elencato nell'istruzione select come una colonna? SELEZIONA DATEPART (ORE, o.orderdate) AS ORA, stato, COUNT (DISTINCT o.orderid) DA – user1466907

+0

il primo sql? o il perno? ti sta dando un errore? – Beth