我有一张如下表格。
date |name |number
5/11/2016 17:00:50| abc |123
5/11/2016 18:00:05| def |456
5/11/2016 18:15:00 |ghi |789
我必须显示上一天每小时创建的行数。 如果在该小时内没有创建任何行,则应显示计数0。 我有一个限制,不使用PL / SQL或多个查询。
我试过下面的查询,但问题是它是如何计算0和计数的行
SELECT TRUNC(SYSDATE ,'HH') - LEVEL/24 AS dates , 0 as count from dual CONNECT BY LEVEL <= 24 union
SELECT TRUNC (date, 'hh') as dates, count(*) as count
FROM table
where date> sysdate -1
GROUP BY TRUNC (date, 'hh')
Date |Count
04-NOV-16 08.00.00 |0
04-NOV-16 09.00.00 |0
04-NOV-16 10.00.00 |0
04-NOV-16 11.00.00 |0
05-NOV-16 12.00.00 |0
05-NOV-16 01.00.00 |0
05-NOV-16 02.00.00 |0
05-NOV-16 03.00.00 |0
05-NOV-16 04.00.00 |0
05-NOV-16 05.00.00 |0
05-NOV-16 06.00.00 |0
05-NOV-16 07.00.00 |0
05-NOV-16 08.00.00 |0
05-NOV-16 09.00.00 |0
05-NOV-16 10.00.00 |0
05-NOV-16 11.00.00 |0
05-NOV-16 12.00.00 |0
05-NOV-16 01.00.00 |0
05-NOV-16 02.00.00 |0
05-NOV-16 03.00.00 |0
05-NOV-16 04.00.00 |0
05-NOV-16 05.00.00 |0
05-NOV-16 05.00.00 |1
05-NOV-16 06.00.00 |0
05-NOV-16 06.00.00 |2
05-NOV-16 07.00.00 |0
我正在使用Oracle 11g,我必须在单个查询中显示结果。
答案 0 :(得分:0)
你会注意到我没有ORDER BY hh
这就是输出看起来很奇怪的原因。此外,我在11月5日上午11点,所以我会回顾所有小时的0!
第一个CTE inputs
仅用于测试(它不是解决方案的一部分)。在查询的其余部分中,将输入替换为您的实际表名,并将列名替换为相同的名称(最好不包括date
和number
!)
with
inputs ( dt, name, nbr ) as (
select to_date('5/11/2016 17:00:50', 'dd/mm/yyyy hh24:mi:ss'), 'abc', 123 from dual
union all
select to_date('5/11/2016 18:00:05', 'dd/mm/yyyy hh24:mi:ss'), 'def', 456 from dual
union all
select to_date('5/11/2016 18:15:00', 'dd/mm/yyyy hh24:mi:ss'), 'ghi', 789 from dual
),
-- end test data; solution (SQL query) begins here, but add the word WITH before d (hh)
d ( hh ) as (
select trunc(sysdate, 'hh') - level/24 from dual connect by level <= 24
)
select d.hh, coalesce(i.ct, 0) as ct
from d left outer join (
select trunc(dt, 'hh') as hh, count(*) as ct
from inputs
where dt >= sysdate - 1
group by trunc(dt, 'hh')
) i
on d.hh = i.hh
;
HH CT
------------------- ----------
2016-11-04 06:00:00 0
2016-11-04 21:00:00 0
2016-11-04 19:00:00 0
2016-11-04 23:00:00 0
[............................]
2016-11-04 10:00:00 0
2016-11-04 22:00:00 0
24 rows selected
答案 1 :(得分:0)
我得到了解决方案,如果您好奇,下面是使用正确解决方案的查询
select t1.dates , NVL(t2.count1,0)
from
(SELECT trunc(sysdate ,'HH') - LEVEL/24 AS dates , 0 as count1 from dual CONNECT BY LEVEL <= 24) t1
full outer join
( SELECT TRUNC (Date_col, 'hh') as dates, count(*) as count1
FROM table
where trunc(date_col)>sysdate -1
GROUP BY TRUNC (date_col, 'hh')) t2
on t1.dates=t2.dates
order by t1.dates desc;
答案 2 :(得分:-1)
你不想要union
。你想要left join
:
WITH d as (
SELECT TRUNC(SYSDATE, 'HH') - LEVEL/24 as dte
FROM dual
CONNECT BY LEVEL <= 24
)
SELECT D.dte, count(t.date) as count
FROM d LEFT JOIN
table t
ON d.dte = TRUNC(date, 'HH') AND date > sysdate - 1
GROUP BY d.dte