sql或pl / sql为一天中的每一分钟返回多个计数

时间:2016-01-18 16:21:47

标签: sql plsql

我有一个包含id列和三个日期列的表。

例如,我目前运行以下命令:(这是一个非常简单的例子,没有where子句)

select count(*), trunc(t.date1,'MI')
from schema.table t
group by trunc(t.date1,'MI')
order by 2;

我为t.date2和t.date3做同样的事情,并将结果合并到excel中。

我正在寻找一个sql查询或匿名plsql块,它将返回当天的每一分钟和每个日期列的计数。

请求的示例输出:

sysdate by minute       count date1    count date2     count date3
1/18/2016 00:00         4              2               12
1/18/2016 00:01         3              10              7
etc..

我感谢社区提供的任何帮助和指导。

谢谢

3 个答案:

答案 0 :(得分:1)

一种方法是使用union all

select bymin, sum(cnt1) as cnt1, sum(cnt2) as cnt2, sum(cnt3) as cnt3
from ((select trunc(t.date1, 'MI') as bymin, count(*) as cnt1, 0 as cnt2, 0 as cnt3
       from schema.table t
       group by trunc(t.date1, 'MI')
      ) union all
      (select trunc(t.date2, 'MI') as bymin, 0, count(*) as cnt2, 0
       from schema.table t
       group by trunc(t.date2, 'MI')
      ) union all
      (select trunc(t.date3, 'MI') as bymin, 0, 0 count(*) as cnt3
       from schema.table t
       group by trunc(t.date3, 'MI')
      )
     ) t
group by bymin;

另一种方法是使用full outer join。但是,这涉及很多coalesce()

答案 1 :(得分:0)

另一种方法是取消列,然后通过例如:

执行条件组
with mins as (select trunc(sysdate) + (level - 1)/1440 dt
              from   dual
              connect by level <= 1440),
      t1 as (select case when d.lvl = 1 then 'date1'
                         when d.lvl = 2 then 'date2'
                         when d.lvl = 3 then 'date3'
                    end dt_type,
                    case when d.lvl = 1 then trunc(dt1, 'mi')
                         when d.lvl = 2 then trunc(dt2, 'mi')
                         when d.lvl = 3 then trunc(dt3, 'mi')
                    end dt
             from   tablename t
                    cross join (select 0 + level lvl from dual connect by level <= 3) d)
select mins.dt,
       count(case when t1.dt_type = 'date1' then t1.dt end) count_dt1,
       count(case when t1.dt_type = 'date2' then t1.dt end) count_dt2,
       count(case when t1.dt_type = 'date3' then t1.dt end) count_dt3
from   mins
       left join t1 on (mins.dt = t1.dt)
group by mins.dt
order by mins.dt;

答案 2 :(得分:0)

请看这个例子。我希望它会对你有所帮助。当然,最好只在该日期从schema.table中选择行以提高性能。

WITH minutes AS (
    SELECT *
    FROM GENERATE_SERIES(
        '2016-01-01 00:00'::TIMESTAMP,
        '2016-01-01 23:59'::TIMESTAMP,
        '1 MINUTE'
    ) AS minute
)
SELECT
    a.minute,
    SUM(CASE WHEN b.date1 >= a.minute AND b.date1 < a.minute + INTERVAL '1 MINUTE' THEN 1 ELSE 0 END) AS c1,
    SUM(CASE WHEN b.date2 >= a.minute AND b.date2 < a.minute + INTERVAL '1 MINUTE' THEN 1 ELSE 0 END) AS c1,
    SUM(CASE WHEN b.date3 >= a.minute AND b.date3 < a.minute + INTERVAL '1 MINUTE' THEN 1 ELSE 0 END) AS c1
FROM minutes a
LEFT JOIN schema.table b ON (TRUE)
GROUP BY a.minute
ORDER BY a.minute ASC