根据日期中的星期几将单行拆分为多行

时间:2019-09-05 10:05:43

标签: sql sql-server date common-table-expression

我有一张这样的桌子

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

在这种情况下,将有3行作为ID的有效起始日期,并且在这3周之间有有效的两次落入-9744

对于ID-9745,有效日期是无穷大,因此我们只需要从有效日期开始就取当前月份中的所有星期

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

有人可以帮我编写查询以获取此输出吗?

谢谢

2 个答案:

答案 0 :(得分:0)

您提到一个“日期”表。如果您有一个,则可以像这样使用join

select distinct t.id, valid_from, t.valid_to, d.month, d.week
from yourtable t join
     date d
     on d.date >= t.valid_from and
        d.date <= t.valid_to;

答案 1 :(得分:0)

如果我正确理解您的问题,则需要列出在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 周。希望对您有帮助。