我正在尝试生成一个输出,以0填充缺失计数。
我正在使用Oracle SQL。到目前为止,我的解决方案基于Grouping records hour by hour or day by day and filling gaps with zero or null并进行了少量添加。
WITH TEMP
AS ( SELECT MINDT + ( (LEVEL - 1) / 24) DDD
FROM (SELECT TRUNC (MIN (MY_TIMESTAMP), 'HH24') MINDT,
TRUNC (MAX (MY_TIMESTAMP), 'HH24') MAXDT
FROM MAIN_TABLE.TABLE_VIEW THV
WHERE MY_TIMESTAMP BETWEEN TO_DATE ('08/01/2018:00:00:00',
'MM/DD/YYYY:HH24:MI:SS')
AND TO_DATE (
'08/03/2018:23:59:59',
'MM/DD/YYYY:HH24:MI:SS')) V
CONNECT BY MINDT + ( (LEVEL - 1) / 24) <= MAXDT)
SELECT TO_CHAR (TRUNC (D1, 'HH24'), 'YYYY-MM-DD HH24'), COUNT (D2), ID
FROM (SELECT NVL (MY_TIMESTAMP, DDD) D1,
MY_TIMESTAMP D2,
THV.ID ID
FROM MAIN_TABLE.TABLE_VIEW THV
RIGHT OUTER JOIN
(SELECT DDD FROM TEMP) AD
ON DDD = TRUNC (MY_TIMESTAMP, 'HH24')
WHERE MY_TIMESTAMP BETWEEN TO_DATE ('08/01/2018:00:00:00',
'MM/DD/YYYY:HH24:MI:SS')
AND TO_DATE ('08/03/2018:23:59:59',
'MM/DD/YYYY:HH24:MI:SS'))
GROUP BY ID, TRUNC (D1, 'HH24')
ORDER BY ID, TRUNC (D1, 'HH24')
现在我得到:
CNT ID DT
4 1 2018-08-01 00
1 1 2018-08-01 01
1 1 2018-08-01 04
20 1 2018-08-01 05
76 1 2018-08-01 07
但是我想要的是:
CNT ID DT
4 1 2018-08-01 00
1 1 2018-08-01 01
0 1 2018-08-01 02
0 1 2018-08-01 03
1 1 2018-08-01 04
20 1 2018-08-01 05
0 1 2018-08-01 06
76 1 2018-08-01 07
任何帮助将不胜感激。
答案 0 :(得分:0)
如果要连接的表具有您期望在结果中拥有的所有时间,则此表运行非常顺畅。要使一个表具有所有时间,它只有24条记录。
它可以是一个临时表,但是如果它是一个真实表,它将把您的报告简化为标准查询。如果定期使用此报告,为什么不准备额外的表格呢?我已经看到DBA具有一个通用的“数字”表,其中包含许多数字,以实现类似的技巧(要获得0-23,请查询表where n between 0 and 23
)。再举一个例子,如果您希望每个单独的日期都为90天,则可以使用0-89的数字表,并将该值添加到开始日期,以便可以在该期间的每个可能的日期加入。