24小时内不同状态的SQL总和按小时计算

时间:2015-09-16 20:01:03

标签: sql count

我试图在24小时组内按小时计算状态。我有订单,订单状态和状态表。

订单表:

+---------+-------------------------+
| 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 |
+---------+-------------------------+

订单状态表:

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

状态表:

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

我尝试编写SQL,显示24小时内状态的计数,以便按小时分组的不同订单:

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

到目前为止,这是我的SQL。我被困在试图得到每个订单状态的总和:

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

2 个答案:

答案 0 :(得分:0)

这应该让你更接近,然后你必须转动:

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)

尝试使用枢轴:

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 

答案 1 :(得分:0)

在这里 - 我忽略了数据中的错误,因为如果状态表确实有像您的示例数据中那样的重复ID,则会失败。

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