首页 > 解决方案 > 根据日期中的月份将单行拆分为多行

问题描述

我有一张这样的桌子

Id      Valid_From    Valid_To
9744    24/06/2019    07/07/2019
9745    12/08/2019    31/12/9999

我想通过加入日期表将这个表拆分为基于星期的多行

Id      Valid_from   Valid_To    Month       Week
9744    24/06/2019   07/07/2019  June        4
9744    24/06/2019   07/07/2019  July        1
9744    24/06/2019   07/07/2019  July        2
9745    12/08/2019   31/12/9999  August      2
9745    12/08/2019   31/12/9999  August      3
9745    12/08/2019   31/12/9999  August      4

在这种情况下,ID 为 9744 的有效起始和有效两行介于这 3 周之间,将有 3 行

对于 ID - 9745,Valid_to 日期是无穷大的,所以我们只需从 valid_from 日期开始计算当前月份的所有星期

然后我只需要在输出中附加月份和周数

有人可以帮我写一个查询来得到这个输出吗?

谢谢

标签: sqlsql-serverdatecommon-table-expression

解决方案


如果我正确理解您的问题,您需要列出这些月份之间存在的所有月份名称和周valid_fromvalid_to。我通过以下查询做到了:

SELECT 
  Q.ID, 
  Q.VALID_FROM,
  Q.VALID_TO,
  Q.MONTH_NAME,
  WEEK_NUMBER
FROM
(
  SELECT
    CEIL((Q.DATES_BETWEEN_INTERVAL - FIRST_DAY_OF_MONTH + 1) / 7) WEEK_NUMBER,
    TO_CHAR(Q.DATES_BETWEEN_INTERVAL, 'MONTH', 'NLS_DATE_LANGUAGE = American') MONTH_NAME,
    Q.* 
  FROM
  (
    SELECT  
      LEVEL + S.VALID_FROM DATES_BETWEEN_INTERVAL,
      TRUNC(LEVEL + S.VALID_FROM, 'MONTH') FIRST_DAY_OF_MONTH,
      S.* FROM
    (
      SELECT T.*, 
        (CASE WHEN EXTRACT(YEAR FROM T.VALID_TO) = 9999 THEN LAST_DAY(T.VALID_FROM) ELSE T.VALID_TO END) - T.VALID_FROM DAYS_COUNT
      FROM AAA_TABLE T
    ) S
    CONNECT BY LEVEL <= S.DAYS_COUNT
  ) Q
) Q
GROUP BY 
  Q.ID, 
  Q.VALID_FROM,
  Q.VALID_TO,
  Q.MONTH_NAME,
  WEEK_NUMBER
ORDER BY
  Q.ID, 
  Q.VALID_FROM,
  Q.VALID_TO,
  Q.MONTH_NAME,
  WEEK_NUMBER;

但如果日期大于一个月的第 28天,则必须有第 5周。希望这会帮助你。


推荐阅读