【问题标题】:Split single row into multiple rows based on week of the month in date根据日期中的月份将单行拆分为多行
【发布时间】:2019-09-05 19:29:03
【问题描述】:

我有一张这样的桌子

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 行作为有效起始和有效两个在这 3 周之间的 ID - 9744

对于 ID - 9745,Valid_to 日期是无穷大的,所以我们只需要从 valid_from 日期算起当月的所有星期

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

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

谢谢

【问题讨论】:

  • 我删除了不一致的数据库标签。请标记您真正使用的数据库。你如何定义week?什么是“日期”表?

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


【解决方案1】:

您提到了“日期”表。如果你有,那么你可以像这样使用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;

【讨论】:

  • 是的,有一个日期表。不应该有任何where子句吗?例如 - d.day_start_date IN ('2019-01-07 00:00:00.000', '2019-01-14 00:00:00.000', '2019-01-21 00:00:00.000', '2019 -01-28 00:00:00.000', '2019-01-29 00:00:00.000') 例如,这列出了日期表中一月份的所有星期开始日期?
  • 如果我们不放置 where 子句,那么我相信它会为每个日期(第 1、第 2、第 3 ......我错了吗?
  • @Vijai 。 . . on 子句处理范围。 select distinct 删除重复项。
【解决方案2】:

如果我正确理解您的问题,您需要列出在 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;

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

【讨论】:

  • 您好,谢谢,但只是想知道使用日期表是否有助于降低查询复杂性?
  • 你如何决定创建日期表?
  • 有一个日历日期表,我们引用日期列,它有 day_start_date、month、week、year ...只是想知道加入这个 Date 表并从那里拉出月份和星期并加入用基表(AAA_TABLE)可以做吗?
  • 是的,我认为这将满足您的要求。我不知道您的日历日期表存在于您的数据库中。我认为您有一个表(在本例中为 AAA_TABLE),您需要编写一个查询来显示示例中的结果。这就是我创建此查询的原因
  • 是的,很抱歉有一个日期表我们可以用来提取月份和星期,你能告诉我合并这个日期表并修改你的查询吗?
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多