我想从范围内的表中选择值。 像这样:
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_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
列是日期。这并不明显,因为您正在进行字符串比较。您应该始终在适用的情况下显式转换为日期,并且应始终将日期存储为日期。从长远来看,它可以省去很多麻烦,因为不可能出现输入错误或比较错误的情况。
关于database - Oracle:选择日期范围内的值以及缺少值的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10946128/