选择查询以返回所有记录的值

时间:2013-10-11 02:45:30

标签: sql oracle select

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

这是我的疑问:

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子句中提供。

2 个答案:

答案 0 :(得分:2)

SQL Fiddle for easy reference

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

这会生成您尝试查询的源,状态和日期的每个组合。

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;

然后你可以完成所有这些并离开join到你的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

答案 1 :(得分: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