database - Oracle:选择日期范围内的值以及缺少值的日期

标签 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,如果你能建议更通用的解决方案,我可以将其扩展以用于小时、月、年;会很棒。

最佳答案

我假设您提供的是 date_fromdate_to。如果是这样,您可以先生成日期列表,然后加入它以获得结果的其余部分。或者,您可以将此查询union 到您的date_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_values 中的 date 列是日期。这并不明显,因为您正在进行字符串比较。您应该始终在适用的情况下显式转换为日期,并且应始终将日期存储为日期。从长远来看,它可以省去很多麻烦,因为不可能出现输入错误或比较错误的情况。

关于database - Oracle:选择日期范围内的值以及缺少值的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10946128/

相关文章:

MySQL时间序列数据分区

database - 分布式事务-为什么我们将记录保存到文件系统?

oracle - Oracle 中的一个实例与多个实例

ios - 如何调整父 View 的大小以符合 subview 的约束

swift - 如何将对象限制为全屏

java - 从 Java Web 服务的操作创建 MySql 数据库

php - 数据 ID 未显示 这是为什么?

python - sqlalchemy 使用 ORM 创建 VIEW

python - 加入所有 PostgreSQL 表并制作一个 Python 字典

sql-server - 在 MS SQL Server 和 Oracle Server 之间同步数据