【问题标题】:Postgres generate_series excluding date rangesPostgres generate_series 不包括日期范围
【发布时间】:2015-10-25 14:30:42
【问题描述】:

我正在创建一个订阅管理系统,并且需要生成未来 2 年即将到来的计费日期列表。我已经能够使用 generate_series 来获取适当的日期:

SELECT i::DATE
FROM generate_series('2015-08-01', '2017-08-01', '1 month'::INTERVAL) i

我需要采取的最后一步是从计算中排除特定日期范围。这些排除的日期范围可以是任何时间范围。此外,它们不应计入 generate_series 的时间范围内。

例如,假设我们排除了从“2015-08-27”到“2015-09-03”的日期范围。生成的 generate_series 应该从计算中排除该周的日期,并且基本上将所有未来月份的计费日期推到未来一周

2015-08-01
2015-09-10
2015-10-10
2015-11-10
2015-12-10

【问题讨论】:

  • 已删除答案,并没有解决真正困难的部分。排除范围很容易。困难的部分是调整它重复出现的模式,在最后添加更多时间以补偿跳过的时间范围,然后调整重复出现的日期。我认为您将需要一个递归 CTE 或一个过程来执行此操作,因为通过在末尾补偿排除添加的行本身可能会被排除,因此我们必须扩展更多行以进行测试...跨度>
  • 我还觉得您的月度计费与允许在几天或几周范围内的排除相结合的效果不佳,因为并非每个月的天数都相同。您可能需要考虑每 30 天而不是每月结算一次。
  • 您的示例似乎是错误的。日期提前了 9 天,但间隔只有 7 天。
  • @CraigRinger 为什么您认为需要在排除天数的基础上扩展 2 年范围?我没有在问题中读到。
  • @Patrick 来自“将所有未来月份的计费日期推到未来一周”。原始发布者应确认其意图并提供完整、正确的预期结果。请编辑问题 Eric。

标签: postgresql date generate-series


【解决方案1】:

首先,您创建一个未来两年日期的时间序列,EXCEPT 您的停电日期:

SELECT dt
FROM generate_series('2015-08-01'::date, '2017-08-01'::date, interval '1 day') AS s(dt)
EXCEPT
SELECT dt
FROM generate_series('2015-08-27'::date, '2015-09-03'::date, interval '1 day') as ex1(dt)

请注意,您可以根据需要拥有任意数量的 EXCEPT 子句。对于个别停电日(而不是范围),您可以使用 VALUES 子句而不是 SELECT

然后您在该时间序列上生成窗口以生成可计费天数的行数:

SELECT row_number() OVER (ORDER BY dt) AS rn, dt
FROM (<query above>) x

然后您选择要结算的日期:

SELECT dt
FROM (<query above>) y
WHERE rn % 30 = 1; -- billing on the first day of the period

(后一个查询遵循 Craig 的 30 天计费建议)

产量:

SELECT dt
FROM (
  SELECT row_number() OVER (ORDER BY dt) AS rn, dt
  FROM (
    SELECT dt
    FROM generate_series('2015-08-01'::date, '2017-08-01'::date, interval '1 day') AS s(dt)
    EXCEPT
    SELECT dt
    FROM generate_series('2015-08-27'::date, '2015-09-03'::date, interval '1 day') as ex1(dt)
  ) x
) y
WHERE rn % 30 = 1;

【讨论】:

    【解决方案2】:

    您必须拆分呼叫以生成排除系列。像这样的东西:

    • 3 个查询的并集
    • 第一个查询将日期从开始拉到排除范围
    • 第二个查询提取排除范围到您的结束日期之间的日期
    • 当您的系列日期均未超出排除范围时,第三个查询会提取日期

    注意:您仍然需要一种方法来遍历排除列表(如果有的话)。此外,此查询可能效率不高,因为此类场景可以通过函数或过程代码更好地处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多