oracle中日期自动补全,没有数据自动补0
1、业务需求
因查询系统内浏览器的使用记录,需要查询某一时间段内使用的数量,数据库中存在默些天没有数据,也没有日期,所以按照常规的查询方法没法查询出所有的日期以及对应的数据。
1.1、正常查询如下*:(如果想直接看结果,请看第二段:实现思路)
SELECT COUNT(*) AS COUNT, TO_CHAR(OPERATETIME, 'yyyy-MM-dd') DATAS
FROM T_S_LOG
WHERE TO_CHAR(OPERATETIME, 'yyyy-MM-dd') >= '2019-01-01' AND
TO_CHAR(OPERATETIME, 'yyyy-MM-dd') <= '2019-01-17' AND LOGLEVEL = 1 AND
USERID ='b5e7f84c5ec9d46eed3c6cac55fce03a'
GROUP BY TO_CHAR(OPERATETIME, 'yyyy-MM-dd')
ORDER BY DATAS
1.2、查询出来的数据如下:2019-01-01、2019-01-05的数据不存在,无法满足需求。
2、实现思路
先通过DUAL表查询出时间段内的所有日期DATAS,然后通过左连接、右连接上表数据COUNT,获取A标的所有日期和B表的所有数据(无数据以0补充);主要设计的有NVL(查询字段,无数据补充字段)、TO_DATE(’’,’’)函数、TO_CHAR(’’,’’)函数、CONNECT BY、TRUNC(‘大日期’,‘小日期’)日期减法函数、LEFT JOIN … ON… .
2.1、自动补全日期SQL
SELECT TO_CHAR(TO_DATE('2019-01-01', 'yyyy-MM-dd') + ROWNUM - 1, 'yyyy-MM-dd') AS DATAS
FROM DUAL
CONNECT BY ROWNUM <= TRUNC(TO_DATE('2019-01-17', 'yyyy-MM-dd') - TO_DATE('2019-01-01', 'yyyy-MM-dd')) + 1
3、实现SQL
3.1、补全之后查询sql
SELECT NVL(B.COUNT, 0), A.DATAS
FROM (SELECT TO_CHAR(TO_DATE('2019-01-01', 'yyyy-MM-dd') + ROWNUM - 1, 'yyyy-MM-dd') AS DATAS
FROM DUAL
CONNECT BY ROWNUM <= TRUNC(TO_DATE('2019-01-17', 'yyyy-MM-dd') - TO_DATE('2019-01-01', 'yyyy-MM-dd')) + 1) A
LEFT JOIN (SELECT COUNT(*) AS COUNT, TO_CHAR(OPERATETIME, 'yyyy-MM-dd') DATAS
FROM T_S_LOG
WHERE TO_CHAR(OPERATETIME, 'yyyy-MM-dd') >= '2019-01-01' AND
TO_CHAR(OPERATETIME, 'yyyy-MM-dd') <= '2019-01-17' AND
LOGLEVEL = 1 AND
USERID IN
(SELECT USERID
FROM DAB_DYINFO
WHERE DAB_SZDZB IN
(SELECT D3.ID
FROM DAA_ORGINFO D3
WHERE D3.DAA_ZTNO = 1
START WITH D3.ID = '1-05'
CONNECT BY PRIOR D3.ID = DAA_ID_SJ))
GROUP BY TO_CHAR(OPERATETIME, 'yyyy-MM-dd')) B
ON A.DATAS = B.DATAS
ORDER BY DATAS;
3.2、完美perfect
4、感想
实现方式有多种:有时需要从不同的方向考虑问题,谢谢大家,有问题请留言。
如果你看到了这里,觉得文章写得不错就给个赞,关注公众号,可订阅更多干货?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢!