我正在使用此命令获取状态:
SELECT DECODE(processed,1,'Complete', 'Incomplete') Last_Day_Report_Status,
COUNT(*)
FROM Table_demo
WHERE run_datetime >= trunc(sysdate)-1
AND run_datetime < trunc(sysdate)
GROUP BY DECODE(processed,1,'Complete','Incomplete');
它应该输出如下:
完成:120
不完整:0
但它只给予: 完成:120
答案 0 :(得分:5)
WITH parameter as (
SELECT 'Complete' as status FROM DUAL
UNION ALL
SELECT 'Incomplete' as status FROM DUAL
)
SELECT parameter.status as Last_Day_Report_Status,
COUNT(status)
FROM parameter
LEFT JOIN Table_demo
ON parameter.status = DECODE(status ,1,'Complete', 'Incomplete')
WHERE run_datetime >= trunc(sysdate)-1
AND run_datetime < trunc(sysdate)
GROUP BY parameter.status;
答案 1 :(得分:0)
此解决方案的优点应该是速度。它将Table_demo汇总为一行,这样就不需要为每个使用过的Table_demo行计算连接。
SELECT
Last_Day_Report_Status,
DECODE(Last_Day_Report_Status, 'Complete', NVL(Completed,0), NVL(Total-Completed,0)) counts
FROM
( SELECT 'Complete' Last_Day_Report_Status FROM DUAL
UNION ALL
SELECT 'Incomplete' Last_Day_Report_Status FROM DUAL
)
OUTER APPLY
( SELECT COUNT(DECODE(processed,1,'Complete')) Completed, COUNT(1) Total
FROM Table_demo
WHERE run_datetime >= TRUNC(SYSDATE)-1
AND run_datetime < TRUNC(SYSDATE)
);
这个问题的一大问题是优化器拒绝首先处理子查询,或者即使在暗示死亡时也作为哈希联接处理,导致总和运行两次,欢迎评论。我所拥有的查询的最明确的优化(尽管1 = 1的丑陋假连接),遗憾的是仍然从联合到求和的嵌套循环,是:
SELECT /*+ ordered */
Last_Day_Report_Status,
DECODE(Last_Day_Report_Status, 'Complete', NVL(Completed,0), NVL(Total-Completed,0)) counts
FROM
( SELECT COUNT(DECODE(processed,1,'Complete')) Completed, COUNT(1) Total
FROM Table_demo
WHERE run_datetime >= TRUNC(SYSDATE)-1
AND run_datetime < TRUNC(SYSDATE)
)
RIGHT OUTER JOIN
( SELECT 'Complete' Last_Day_Report_Status FROM DUAL
UNION ALL
SELECT 'Incomplete' Last_Day_Report_Status FROM DUAL
) ON 1=1;
优化器觉得无法使用ORDERED
提示请求按查询顺序执行子查询。
给定优化路径并假设Table_demo可能很大,求和可以实现(预先封装)。具体化过程具有启动成本,因此在每秒执行100次或1000次的循环中可能是昂贵的。尽管计数实体化查询被访问两次(对于联合的每一行一次),但它仍然需要未记录的/*+ MATERIALIZE */
提示来阻止它INLINE
编辑,ROWNUM
在{{{ 1}}强制这不会起作用,因为它知道只有一行。这提供了一个很好的优化:
SELECT
我使用的优化版本是Oracle 12.1.0.1 SE。我在没有检查执行跟踪的情况下采用了面值的解释计划。