Oracle:选择日期范围内的值以及缺少值的天数

时间:2012-06-08 09:20:01

标签: database oracle view oracle10g

我想从范围内的表中选择值。 像这样:

SELECT
  date_values.date_from,
  date_values.date_to,
  sum(values.value)
FROM values
  inner join date_values on values.id_date = date_values.id
  inner join date_units on date_values.id_unit = date_units.id
WHERE
  date_values.date_from >= '14.1.2012' AND
  date_values.date_to <= '30.1.2012' AND
  date_units.id = 4
GROUP BY
  date_values.date_from,
  date_values.date_to
ORDER BY
  date_values.date_from,
  date_values.date_to;

但是这个查询只给我回溯天数,其中有任何值。像这样:

14.01.12    15.01.12    66
15.01.12    16.01.12    4
17.01.12    18.01.12    8
...etc

(这里缺少16.01.12至17.01.12)

但我也想选择缺失值,如下所示:

14.01.12    15.01.12    66
15.01.12    16.01.12    4
16.01.12    17.01.12    0
17.01.12    18.01.12    8
...etc

我不能使用PL / SQL,如果能建议更广泛的解决方案,我可以扩展用于小时,月,年;会很棒的。

1 个答案:

答案 0 :(得分:2)

我假设你提供date_fromdate_to。如果是这样,您可以先生成日期列表,然后加入它以获得结果的剩余部分。或者,您可以uniondate_values表格进行union此查询, select to_date('14.1.2012','dd.mm.yyyy') + level - 1 as date_from , to_date('14.1.2012','dd.mm.yyyy') + level as date_to from dual connect by level <= to_date('30.1.2012','dd.mm.yyyy') - to_date('14.1.2012','dd.mm.yyyy') 执行此操作会删除任何额外数据。

如果这是生成日期列表的方式:

with the_dates as (
 select to_date('14.1.2012','dd.mm.yyyy') + level - 1 as date_from
      , to_date('14.1.2012','dd.mm.yyyy') + level as date_to
   from dual
connect by level <= to_date('30.1.2012','dd.mm.yyyy') 
                  - to_date('14.1.2012','dd.mm.yyyy')
         )
SELECT
  dv.date_from,
  dv.date_to,
  sum(values.value)
FROM values
  inner join ( select the_dates.date_from, the_dates.date_to, date_values.id
                 from the_dates
                 left outer join date_values
                   on the_dates.date_from = date_values.date_from ) dv
     on values.id_date = dv.id
  inner join date_units on date_values.id_unit = date_units.id
WHERE
  date_units.id = 4
GROUP BY
  dv.date_from,
  dv.date_to
ORDER BY
  dv.date_from,
  dv.date_to;

您的查询可能会变为

with

date语法称为子查询因子,在这种情况下并不是真的需要,但它使代码更清晰。

我还假设date_values中的{{1}}列是日期。当你进行字符串比较时,这并不明显。您应始终明确转换为适用的日期,并始终将日期存储为日期。从长远来看,它可以省去很多麻烦,因为不可能输入错误或不正确地比较。