1

我正在尝试检索一些报告数据

这是我的查询:

SELECT sourceCode as "Source", to_char(myTimestamp, 'YYYY-MM-DD') as "Date", statusCode as "Status", count(*) as "Count"
FROM archive_table
WHERE myTimestamp BETWEEN TO_TIMESTAMP('2013-09-30','yyyy-mm-dd') AND TO_TIMESTAMP('2013-10-05','yyyy-mm-dd')
GROUP BY sourceCode, to_char(myTimestamp, 'YYYY-MM-DD'), statusCode
ORDER BY 1, 2, 3

这是输出:

Source  Date    Status  Count
Source1 9/30/2013   C   10
Source1 10/1/2013   C   8
Source1 10/2/2013   C   24
Source1 10/2/2013   O   4
Source2 10/4/2013   C   22
Source2 10/4/2013   O   7
Source3 10/1/2013   C   2
Source4 9/30/2013   C   15
Source4 9/30/2013   O   15
Source4 10/1/2013   C   24
Source4 10/1/2013   O   12

我想看到的是所有 0 的计数,例如日期为 9/30/2013 的 Source1 在数据库中没有状态 0,所以我希望它显示:

Source1  9/30/2013  O  0

另一个例子,现在 2013 年 9 月 30 日完全有 Source2,所以它应该显示:

Source2  9/30/2013  O  0
Source2  9/30/2013  C  0

我希望有一个简单的方法来做到这一点。有关其他信息,只有 4 个“来源”,状态为“O”或“C”,显然日期范围在 where 子句中提供。

4

2 回答 2

2

SQL Fiddle 便于参考

最简单的方法是,如果您有一个包含可能的来源、状态和日期的值表。即使您不这样做,您仍然可以动态生成可以支持您的查询的派生表。

这会生成您尝试查询的 Source、Status 和 Date 的每个组合。

select
  *
from
  (select 'Source1' Source from Dual
   union select 'Source2' from Dual
   union select 'Source3' from Dual
   union select 'Source4' from Dual
   ) s
  cross join (
    select 'O' Status from Dual
    union select 'C' from Dual
   ) c
  cross join (
    select '2013-09-30' Dt from Dual
    union select '2013-10-01' from Dual
    union select '2013-10-02' from Dual
    union select '2013-10-03' from Dual
    union select '2013-10-04' from Dual
    union select '2013-10-05' from Dual
   ) d;

然后,您可以使用所有这些并左连接到您的archive_table,并对捏造的数据而不是您的基表进行分组,并对您的archive_table 列之一进行计数。

select
  s.Source,
  c.Status,
  d.Dt,
  count(t.Source)
from
  (select 'Source1' Source from Dual
   union select 'Source2' from Dual
   union select 'Source3' from Dual
   union select 'Source4' from Dual
   ) s
  cross join (
    select 'O' Status from Dual
    union select 'C' from Dual
   ) c
  cross join (
    select '2013-09-30' Dt from Dual
    union select '2013-10-01' from Dual
    union select '2013-10-02' from Dual
    union select '2013-10-03' from Dual
    union select '2013-10-04' from Dual
    union select '2013-10-05' from Dual
   ) d
  left join test t
    on s.Source = t.Source
       and c.Status = t.Status
       and d.Dt = t.Dt
group by
  s.Source,
  c.Status,
  d.Dt
于 2013-10-11T03:12:19.233 回答
1

不要指定日期范围内的每个日期,而是使用以下内容,您只需要包括开始日期和结束日期:

SELECT
    TO_DATE('09/30/2013','mm/dd/yyyy') - 1 + LEVEL dt
FROM dual
    CONNECT BY
LEVEL <= ( TO_DATE('10/05/2013','mm/dd/yyyy')
         - TO_DATE('09/30/2013','mm/dd/yyyy')) + 1
于 2013-10-11T04:56:01.920 回答