Oracle:选择日期范围内缺少值的日期的值
Posted
技术标签:
【中文标题】Oracle:选择日期范围内缺少值的日期的值【英文标题】:Oracle: Select values in date range with days where value is missing 【发布时间】:2012-06-08 09:20:01 【问题描述】:我想从范围内的表中选择值。 像这样的:
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,如果您能建议更通用的解决方案,我可以将其扩展到小时、月、年;会很棒的。
【问题讨论】:
在我看来你需要一个外连接。日期 16.01.12 到 17.01.12 似乎在 date_units 表中没有相应的记录。我说的对吗? date_values 表中缺少日期 16.01.12 到 17.01.12。 Date_units 是表,我在其中存储范围类型(如天(date_units.id = 4)、小时、月、周、年......)。我认为,我“只是”需要生成第二个临时日期表并与这两个表相交。问题是如何生成这个表? 【参考方案1】:我假设您提供的是 date_from
和 date_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
列是日期。当您进行字符串比较时,这并不明显。您应始终明确转换为适用的日期,并且应始终将日期存储为日期。从长远来看,它可以省去很多麻烦,因为不会出现输入错误或比较错误的情况。
【讨论】:
以上是关于Oracle:选择日期范围内缺少值的日期的值的主要内容,如果未能解决你的问题,请参考以下文章