在Oracle SQL中,我尝试在两个日期列之间的一列中打印日期,并根据ID进行分组

vshtjzan  于 2023-04-20  发布在  Oracle
关注(0)|答案(2)|浏览(165)

下面是一个例子,我有一个类似的数据,我期待两个日期字段之间的concat日期
表ABC
| ID|从|到|
| --------------|--------------|--------------|
| 1|2019 - 03 - 12|2019 - 05 - 22|
| 1|2019 - 05 - 21 00:00:00|2019 - 06 - 15|
| 二|2023年1月1日|2023年4月18日|
| 三|2020年3月29日|2019 - 06 - 21 00:00:00|
| 三|2019 - 05 - 21|2019 - 07 - 11 00:00:00|
| 三|2022年12月12日|2023年3月20日|
我期待得到从和到列之间的日期和打印结果列与分组的基础上ID字段分隔;输出应该类似于下面的内容。
| ID|结果|
| --------------|--------------|
| 1|2021年3月1日;2021年4月1日;2021年5月1日;01/06/2021|
| 二|2023年1月1日;2023年2月1日;2023年3月1日;01/04/2023|
| 三|2020年3月1日;2020年4月1日;2020年5月1日;2020年6月1日;2023年5月1日;2023年6月1日;2023年7月1日;2022年1月12日;2023年1月1日;2023年2月1日;01/03/2023|
感谢您的评分

xurqigkl

xurqigkl1#

这里有一个选择:
样本数据:

SQL> with abc (id, date_from, date_to) as
  2    (select 1, date '2021-03-12', date '2021-05-22' from dual union all
  3     select 1, date '2022-06-05', date '2022-06-15' from dual union all
  4     select 2, date '2023-01-01', date '2023-04-18' from dual union all
  5     select 3, date '2020-03-29', date '2020-06-06' from dual union all
  6     select 3, date '2023-05-31', date '2023-07-11' from dual union all
  7     select 3, date '2022-12-12', date '2023-03-20' from dual
  8    )

查询:查找FROMTO日期之间的月数(截断为每月1号),并在ADD_MONTHS函数中使用它来创建所需日期的列表:

9  select id,
 10    listagg(add_months(trunc(date_from, 'mm'), column_value - 1), ', ')
 11      within group (order by add_months(trunc(date_from, 'mm'), column_value - 1)) result
 12  from abc cross join
 13  table(cast(multiset(select level from dual
 14                      connect by level <= months_between(trunc(date_to, 'mm'), trunc(date_from, 'mm')) + 1
 15                     ) as sys.odcinumberlist))
 16  group by id;

 ID RESULT
--- ----------------------------------------------------------------------------------------------------------------------------------
  1 01/03/2021, 01/04/2021, 01/05/2021, 01/06/2022
  2 01/01/2023, 01/02/2023, 01/03/2023, 01/04/2023
  3 01/03/2020, 01/04/2020, 01/05/2020, 01/06/2020, 01/12/2022, 01/01/2023, 01/02/2023, 01/03/2023, 01/05/2023, 01/06/2023, 01/07/2023

SQL>
vsikbqxv

vsikbqxv2#

您可以使用递归子查询factoring子句来生成所有月份,然后进行聚合:

WITH months (id, "FROM", "TO") AS (
  SELECT id, TRUNC("FROM", 'MM'), TRUNC("TO", 'MM') FROM abc
UNION ALL
  SELECT id, ADD_MONTHS("FROM", 1), "TO" FROM months WHERE "FROM" < "TO"
)
SELECT id,
       LISTAGG(DISTINCT TO_CHAR("FROM", 'DD/MM/YYYY'), '; ')
         WITHIN GROUP (ORDER BY "FROM") AS result
FROM   months
GROUP BY id;

其中,对于样本数据:

CREATE TABLE ABC (ID, "FROM", "TO") AS
SELECT 1, DATE '2021-03-12', DATE '2021-05-22' FROM DUAL UNION ALL
SELECT 1, DATE '2022-06-15', DATE '2022-06-15' FROM DUAL UNION ALL
SELECT 2, DATE '2023-01-01', DATE '2023-04-18' FROM DUAL UNION ALL
SELECT 3, DATE '2020-03-29', DATE '2020-06-06' FROM DUAL UNION ALL
SELECT 3, DATE '2023-05-31', DATE '2023-07-11' FROM DUAL UNION ALL
SELECT 3, DATE '2022-12-12', DATE '2023-03-20' FROM DUAL;
  • 注意:FROMTO是保留字,不应用作标识符。如果您必须使用它们,则必须在所有使用它们的地方引用它们(并且始终使用一致的大小写)。*

输出:
| ID|结果|
| --------------|--------------|
| 1|2021年3月1日;2021年4月1日;2021年5月1日;01/06/2022|
| 二|2023年1月1日;2023年2月1日;2023年3月1日;01/04/2023|
| 三|2020年3月1日;2020年4月1日;2020年5月1日;2020年6月1日;2022年1月12日;2023年1月1日;2023年2月1日;2023年3月1日;2023年5月1日;2023年6月1日;01/07/2023|
fiddle

相关问题