COUNT或SUM(CASE)来自单列中的单列

时间:2014-11-01 20:08:20

标签: sql database oracle aggregate-functions

我遇到了一个问题,我几个小时都在盯着看似无法解决的问题。
我有一张表格如下:

CALLS  
CALL_REF {PK}  
TIME  
CALLER_ID {FK}  
DETAIL  
TAKEN_BY {FK}  
ASSIGNED_TO {FK}  
STATUS

示例行为:

1411 8/19/2014 1808 0093 "Detail" AB2 EB1 Closed  
1372 8/19/2014 1238 0096 "Detail" MM1 MW1 Open  

我需要做的是计算特定日期的关闭和开放金额以及创建输出的特定时间:

Date        Shift   Status  Calls  
19-AUG-14   early   Closed  47  
19-AUG-14   early   Open    1  
19-AUG-14   late    Closed  38

转移来自另一个表。

到目前为止,我有这个:

SELECT shifts.shift_date AS "Date", 
       shifts.shift_time AS "Time", 
       calls.status      AS "Status", 
       SUM(CASE 
             WHEN calls.status = 'Closed' THEN 1 
             ELSE NULL 
           end)          AS "Open Calls", 
       SUM(CASE 
             WHEN calls.status = 'Open' THEN 1 
             ELSE NULL 
           end)          AS "Closed Calls" 
FROM   calls 
       INNER JOIN shifts 
               ON shifts.shift_date = calls.call_date 
WHERE  calls.call_date = '19-AUG-14' 
       AND calls.call_time BETWEEN TO_DATE('08:00', 'HH24:MI') AND 
                                   TO_DATE('14:00', 'HH24:MI') 
        OR calls.call_date = '19-AUG-14' 
           AND calls.call_time BETWEEN TO_DATE('14:00', 'HH24:MI') AND 
                                       TO_DATE('20:00', 'HH24:MI') 
GROUP  BY shifts.shift_date, 
          shifts.shift_time, 
          calls.status 
ORDER  BY shifts.shift_time, 
          calls.status; 

哪个输出:

Date       Time    Status   Open Calls  Closed Calls  
19-AUG-14   Early   Closed              85  
19-AUG-14   Early   Open        1  
19-AUG-14   Late    Closed              85  
19-AUG-14   Late    Open        1

显然这是错误的,但我对于如何将两者结合并在两个换档时间之间将它们分开是无能为力的。 请帮忙!

如果需要,这里是数据库的完整布局。 http://i.stack.imgur.com/mKGHU.png

enter image description here

编辑:
我现在正在使用||在两个sum语句之间将它们移动到同一列中。然而,这些数字仍然是总数。他们需要在早班和晚班之间分开。

SELECT SHIFTS.SHIFT_DATE AS "Date", 
       SHIFTS.SHIFT_TIME AS "Time", 
       CALLS.STATUS AS "Status",
       SUM(CASE 
             WHEN CALLS.STATUS = 'Closed' THEN 1 
             ELSE NULL END) ||
       SUM(CASE 
             WHEN CALLS.STATUS = 'Open' THEN 1 
             ELSE NULL END) AS "Calls" 
FROM CALLS 
INNER JOIN SHIFTS
        ON SHIFTS.SHIFT_DATE = CALLS.CALL_DATE 
WHERE CALLS.CALL_DATE = '19-AUG-14' 
  AND (CALLS.CALL_TIME BETWEEN TO_DATE('08:00','HH24:MI') 
  AND TO_DATE('14:00','HH24:MI') 
OR CALLS.CALL_DATE = '19-AUG-14' 
  AND CALLS.CALL_TIME BETWEEN TO_DATE('14:00','HH24:MI') AND TO_DATE('20:00','HH24:MI') 
)
GROUP BY SHIFTS.SHIFT_DATE, 
         SHIFTS.SHIFT_TIME, 
         CALLS.STATUS
ORDER BY SHIFTS.SHIFT_TIME, 
         CALLS.STATUS;

2 个答案:

答案 0 :(得分:0)

部分语法可能不正确,因为我不熟悉Oracle,但我认为下面的查询应该根据原始查询为您提供所需的结果。

SELECT
    Date
    , Shift
    , Status
    , COUNT(*) AS "Calls"

FROM
    (
        SELECT
            SHIFTS.SHIFT_DATE AS "Date"
            , CASE
                WHEN SHIFTS.SHIFT_TIME BETWEEN TO_DATE('08:00','HH24:MI')
                                           AND TO_DATE('14:00','HH24:MI')
                    THEN 'Early'
                ELSE 'Late'
            END AS "Shift"
            , CALLS.STATUS AS "Status"

        FROM
            CALLS
            INNER JOIN SHIFTS
                ON  CALLS.CALL_DATE = SHIFTS.SHIFT_DATE

        WHERE
            CALLS.CALL_DATE = '19-AUG-14'
            AND CALLS.CALL_TIME BETWEEN TO_DATE('08:00','HH24:MI')
                                    AND TO_DATE('20:00','HH24:MI')
    ) AS ShiftGroup

GROUP BY
    Date
    , Shift
    , Status

答案 1 :(得分:0)

实际上它很明显(现在我再次看它)。您的预测包括状态:

   calls.status      AS "Status", 

因此,您必须在group by子句中包含Status,这意味着您的聚合将仅与仅具有该状态的记录相加,因此每行上的一个聚合为空。我有一个SQL小提琴,你的查询的简化版本。 Check it out.

解决方案是删除状态:

SELECT SHIFTS.SHIFT_DATE AS "Date", 
       SHIFTS.SHIFT_TIME AS "Time", 
       SUM(CASE 
             WHEN CALLS.STATUS = 'Closed' THEN 1 
             ELSE NULL END) as "Closed Calls",
       SUM(CASE 
             WHEN CALLS.STATUS = 'Open' THEN 1 
             ELSE NULL END) AS "Open Calls" 
FROM CALLS 
INNER JOIN SHIFTS
        ON SHIFTS.SHIFT_DATE = CALLS.CALL_DATE 
WHERE CALLS.CALL_DATE = '19-AUG-14' 
  AND (CALLS.CALL_TIME BETWEEN TO_DATE('08:00','HH24:MI') 
  AND TO_DATE('14:00','HH24:MI') 
OR CALLS.CALL_DATE = '19-AUG-14' 
  AND CALLS.CALL_TIME BETWEEN TO_DATE('14:00','HH24:MI') AND TO_DATE('20:00','HH24:MI') 
)
GROUP BY SHIFTS.SHIFT_DATE, 
         SHIFTS.SHIFT_TIME
ORDER BY SHIFTS.SHIFT_TIME;