如何在sql oracle中获取开始日期和结束日期范围之间的所有年份
How to get all years between a range of begin and end date in sql oracle
我有一个tableevaluations
这样的
我想通过枚举两个范围之间的所有年份将 bgn_year
和 end_year
转换为 eval_year。结果将如下所示:
我尝试通过以下方式连接:
select employee,
evaluator_type,
EVALUATOR,
(bgn_year-1)+level as eval_year
from evaluations
connect by (bgn_year-1)+level <=end_year
但是我有很多重复的行。我可以添加一个独特的,但我不认为这是这样做的方式。
应该是这样的(第 1 - 7 行中的示例数据;您需要的查询从第 8 行开始):
SQL> with evaluations (employee, bgn_year, end_year, evaluator_type, evaluator)
2 as
3 (select 'A', 2019, 2021, 'POS1', 'X' from dual union all
4 select 'A', 2018, 2021, 'POS2', 'Y' from dual union all
5 select 'B', 2019, 2020, 'POS1', 'Z' from dual union all
6 select 'B', 2020, 2021, 'POS1', 'X' from dual
7 )
8 select employee,
9 --
10 bgn_year + column_value - 1 as eval_year,
11 --
12 evaluator_type,
13 evaluator
14 from evaluations cross join
15 table(cast(multiset(select level from dual
16 connect by level <= end_year - bgn_year + 1
17 ) as sys.odcinumberlist));
EMPLOYEE EVAL_YEAR EVALUATOR_TYPE EVALUATOR
---------- ---------- --------------- ----------
A 2019 POS1 X
A 2020 POS1 X
A 2021 POS1 X
A 2018 POS2 Y
A 2019 POS2 Y
A 2020 POS2 Y
A 2021 POS2 Y
B 2019 POS1 Z
B 2020 POS1 Z
B 2020 POS1 X
B 2021 POS1 X
11 rows selected.
SQL>
以下是使用标准 SQL 递归查询的方法:
with cte (employee, bgn_year, end_year, evaluator_type, evaluator, year) as
(
select employee, bgn_year, end_year, evaluator_type, evaluator, bgn_year from evaluations
union all
select employee, bgn_year, end_year, evaluator_type, evaluator, year + 1 from cte
where year < end_year
)
select employee, year, evaluator_type, evaluator
from cte
order by employee, bgn_year, evaluator_type, evaluator, year;
演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=588fdf9b08b7d5ac49ad830c5269eb62
我有一个tableevaluations
这样的
我想通过枚举两个范围之间的所有年份将 bgn_year
和 end_year
转换为 eval_year。结果将如下所示:
我尝试通过以下方式连接:
select employee,
evaluator_type,
EVALUATOR,
(bgn_year-1)+level as eval_year
from evaluations
connect by (bgn_year-1)+level <=end_year
但是我有很多重复的行。我可以添加一个独特的,但我不认为这是这样做的方式。
应该是这样的(第 1 - 7 行中的示例数据;您需要的查询从第 8 行开始):
SQL> with evaluations (employee, bgn_year, end_year, evaluator_type, evaluator)
2 as
3 (select 'A', 2019, 2021, 'POS1', 'X' from dual union all
4 select 'A', 2018, 2021, 'POS2', 'Y' from dual union all
5 select 'B', 2019, 2020, 'POS1', 'Z' from dual union all
6 select 'B', 2020, 2021, 'POS1', 'X' from dual
7 )
8 select employee,
9 --
10 bgn_year + column_value - 1 as eval_year,
11 --
12 evaluator_type,
13 evaluator
14 from evaluations cross join
15 table(cast(multiset(select level from dual
16 connect by level <= end_year - bgn_year + 1
17 ) as sys.odcinumberlist));
EMPLOYEE EVAL_YEAR EVALUATOR_TYPE EVALUATOR
---------- ---------- --------------- ----------
A 2019 POS1 X
A 2020 POS1 X
A 2021 POS1 X
A 2018 POS2 Y
A 2019 POS2 Y
A 2020 POS2 Y
A 2021 POS2 Y
B 2019 POS1 Z
B 2020 POS1 Z
B 2020 POS1 X
B 2021 POS1 X
11 rows selected.
SQL>
以下是使用标准 SQL 递归查询的方法:
with cte (employee, bgn_year, end_year, evaluator_type, evaluator, year) as
(
select employee, bgn_year, end_year, evaluator_type, evaluator, bgn_year from evaluations
union all
select employee, bgn_year, end_year, evaluator_type, evaluator, year + 1 from cte
where year < end_year
)
select employee, year, evaluator_type, evaluator
from cte
order by employee, bgn_year, evaluator_type, evaluator, year;
演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=588fdf9b08b7d5ac49ad830c5269eb62