显示在最后一天中每小时创建的行数,在未创建行时显示0计数

时间:2016-11-05 15:28:03

标签: sql oracle

我有一张如下表格。

 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,我必须在单个查询中显示结果。

3 个答案:

答案 0 :(得分:0)

你会注意到我没有ORDER BY hh这就是输出看起来很奇怪的原因。此外,我在11月5日上午11点,所以我会回顾所有小时的0!

第一个CTE inputs仅用于测试(它不是解决方案的一部分)。在查询的其余部分中,将输入替换为您的实际表名,并将列名替换为相同的名称(最好不包括datenumber!)

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