GROUP BY在ORACLE中的小计

时间:2018-11-19 19:49:19

标签: sql oracle oracle11g

这是我的桌子。

TASK_CD    |  STATUS | DUE_DATE
----------------------------------
T0001      |  NW     | SYSDATE + 1
T0001      |  IP     | SYSDATE 
T0001      |  AG     | SYSDATE
T0002      |  NW     | SYSDATE - 1
T0002      |  NW     | SYSDATE - 2
T0003      |  AG     | SYSDATE + 1

这是我现在拥有的查询

select TASK_CD, STATUS, SUM(1) TOTALS, 
SUM(CASE WHEN (TRUNC(DUE_DATE ) > SYSDATE) then 1 else 0 end) FUTURE, 
SUM(CASE WHEN (TRUNC(DUE_DATE ) = SYSDATE) then 1 else 0 end) TODAY, 
SUM(CASE WHEN (TRUNC(DUE_DATE ) < SYSDATE) then 1 else 0 end) OVERDUE, 
FROM TM_TASK GROUP BY TASK_CD, STATUS;

结果将

TASK_CD | STATUS | TOTALS | FUTURE | TODAY | OVERDUE
----------------------------------------------------
T0001   | NW     | 1      | 1      | 0     | 0
T0001   | IP     | 1      | 0      | 1     | 0
T0001   | AG     | 1      | 0      | 1     | 0
T0002   | NW     | 2      | 0      | 0     | 2
T0003   | AG     | 1      | 1      | 0     | 0

通过从选择和分组中删除状态,我得到了

TASK_CD | TOTALS | FUTURE | TODAY | OVERDUE
-----------------------------------------------
T0001   | 3      | 1      | 2     | 0
T0002   | 2      | 0      | 0     | 2
T0003   | 1      | 1      | 0     | 0

有没有一种方法可以将两者合并并合并结果,给我TOTALS_ALL,FUTURE_TOTALS,OVERDUE_TOTALS,TODAY_TOTALS,这些是当不考虑GROUP BY的状态时的总和。

TASK_CD | STATUS | TOTALS | FUTURE | TODAY | OVERDUE| TOTALS_ALL | FUTURE_TOTAL | TODAY_TOTAL | OVERDUE_TOTAL
T0001   | NW     | 1      | 1      | 0     | 0      | 3          | 1
             | 2           | 0
T0001   | IP     | 1      | 0      | 1     | 0      | 3          | 1
             | 2           | 0
T0001   | AG     | 1      | 0      | 1     | 0      | 3          | 1
             | 2           | 0
T0002   | NW     | 2      | 0      | 0     | 2      | 2          | 0
             | 0           | 2
T0003   | AG     | 1      | 1      | 0     | 0      | 1          | 1
             | 0           | 0

2 个答案:

答案 0 :(得分:2)

您可以使用subquery factoring clause(通常称为通用表表达)来生成初始数据集,然后使用分析SUM()进行汇总

TRUNC(DUE_DATE ) > SYSDATE

这是您的原始查询(稍有修改,请参见下文),然后是每个任务代码的解析总和。解析总和与总和相同,但不将结果放在每一行上。

您可以在db<>fiddle上看到它的作用。

您会注意到我已更改您的日期逻辑。这是因为due_date >= trunc(sysdate) + 1等于说今天午夜大于第二秒。我已将其更改为 {"name": "John Doe", "email":"jdoe@test.com", "city": "London"} ,这是此秒是在明天午夜或之后。我以类似的方式更改了所有日期逻辑。

答案 1 :(得分:2)

您将使用窗口功能:

for (std::vector<myString>::iterator iter = myVector.begin(); iter != myVector.end(); ++iter = iter)
{
   ...
}