SQL:按 /窗口函数与2列的组合分区,由今天分开

发布于 2025-02-12 00:25:55 字数 658 浏览 0 评论 0 原文

我正在尝试在Postgres中创建一个实现的视图,其中I总和2列,具体取决于今天的日期。

在下图中,有一个我要实现的查询的示例:

如果今天是“ 2022-06-06”:

  • 2022-06-05:1+2+2+3+3+4+4+5
  • 2022-06-06: 1+2+3+4+5+6+6+107
  • 2022-06-07:1+2+3+3+4+4+5+6+107+108

http://sqlfiddle.com/#!15/538EA7/1 更新: http://sqlfiddle.com/#!15/bef30/3

非常感谢任何帮助!

旧图像:

编辑:更新的小提琴和图像

I am trying to create a materialized-view in postgres, where I sum 2 columns, depending on todays date within a window function.

In the below picture there is an example of the query I am trying to achieve:

If today is the '2022-06-06':

  • 2022-06-05: 1+2+3+4+5
  • 2022-06-06: 1+2+3+4+5+6+107
  • 2022-06-07: 1+2+3+4+5+6+107+108

enter image description here

Here is a sample fiddle with date:

http://sqlfiddle.com/#!15/538ea7/1 Updated: http://sqlfiddle.com/#!15/bef30/3

Would greatly appreciate any help!

Old Image:

enter image description here

Edit: Updated Fiddle and Image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

[浮城] 2025-02-19 00:25:55

如果我正确理解了您,则需要以下结果

 user_id | date       | actual | scheduled | sum
 ------: | :--------- | -----: | --------: | --:
       1 | 2022-06-01 |      1 |       100 |   1
       1 | 2022-06-02 |      2 |       101 |   3
       1 | 2022-06-03 |      3 |       103 |   6
       1 | 2022-06-04 |      4 |       104 |  10
       1 | 2022-06-05 |      5 |       105 |  15
       2 | 2022-06-06 |      6 |       106 |  21
       2 | 2022-06-07 |      7 |       107 | 128
       2 | 2022-06-08 |      8 |       108 | 236
       2 | 2022-06-09 |      9 |       109 | 345
       2 | 2022-06-10 |     10 |       110 | 455

,然后可以使用此类查询

SELECT
    user_id,
    date,
    actual,
    scheduled,
    SUM(CASE WHEN date <= '2022-06-6' THEN actual ELSE scheduled END)
        OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM table_1    

If I understood you correctly, you need the following result

 user_id | date       | actual | scheduled | sum
 ------: | :--------- | -----: | --------: | --:
       1 | 2022-06-01 |      1 |       100 |   1
       1 | 2022-06-02 |      2 |       101 |   3
       1 | 2022-06-03 |      3 |       103 |   6
       1 | 2022-06-04 |      4 |       104 |  10
       1 | 2022-06-05 |      5 |       105 |  15
       2 | 2022-06-06 |      6 |       106 |  21
       2 | 2022-06-07 |      7 |       107 | 128
       2 | 2022-06-08 |      8 |       108 | 236
       2 | 2022-06-09 |      9 |       109 | 345
       2 | 2022-06-10 |     10 |       110 | 455

Then you can use a query like this

SELECT
    user_id,
    date,
    actual,
    scheduled,
    SUM(CASE WHEN date <= '2022-06-6' THEN actual ELSE scheduled END)
        OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM table_1    

Working demo

离线来电— 2025-02-19 00:25:55

我认为您想要的功能是累积聚合,但是在这样做之前,您可以在/之后添加新列以正确分区。

这会做您期望的吗?

WITH CTE_PART AS (
  SELECT 
    user_id, 
    date, 
    actual, 
    scheduled, 
    CASE WHEN date <= '2022-06-06' THEN 'Before' ELSE 'After' END as BeforeAfterPartitionId 
  FROM 
    table_1
), 
CTE_CUMULATIVE AS (
  SELECT 
    *, 
    SUM(actual) OVER(
      PARTITION BY user_id, 
      BeforeAfterPartitionId 
      ORDER BY 
        date ROWS BETWEEN UNBOUNDED PRECEDING 
        AND CURRENT ROW
    ) as actual_sum, 
    SUM(scheduled) OVER(
      PARTITION BY user_id, 
      BeforeAfterPartitionId 
      ORDER BY 
        date ROWS BETWEEN UNBOUNDED PRECEDING 
        AND CURRENT ROW
    ) as sched_sum 
  FROM 
    CTE_PART
), 
CTE_PRIORS AS (
  SELECT 
    user_id, 
    date, 
    SUM(actual_sum) as PRIORS 
  FROM 
    CTE_CUMULATIVE 
  WHERE 
    date = '2022-06-06' 
  GROUP BY 
    user_id, 
    date
) 
SELECT 
  A.user_id, 
  A.date, 
  A.actual, 
  A.scheduled, 
  case when A.beforeafterpartitionId = 'Before' THEN A.actual_sum ELSE A.sched_sum + coalesce(B.PRIORS, 0) END as want 
FROM 
  CTE_CUMULATIVE A 
  LEFT OUTER JOIN CTE_PRIORS B ON A.user_id = B.user_id 
  AND A.date >= B.date 
ORDER BY 
  user_id, 
  date;

http://sqlfiddle.com/#!15/bef30/bef30/14

I think the function you want is Cumulative Aggregation, but before doing so you can add a new column Before/After to get it to partition correctly.

Does this do what you expect?

WITH CTE_PART AS (
  SELECT 
    user_id, 
    date, 
    actual, 
    scheduled, 
    CASE WHEN date <= '2022-06-06' THEN 'Before' ELSE 'After' END as BeforeAfterPartitionId 
  FROM 
    table_1
), 
CTE_CUMULATIVE AS (
  SELECT 
    *, 
    SUM(actual) OVER(
      PARTITION BY user_id, 
      BeforeAfterPartitionId 
      ORDER BY 
        date ROWS BETWEEN UNBOUNDED PRECEDING 
        AND CURRENT ROW
    ) as actual_sum, 
    SUM(scheduled) OVER(
      PARTITION BY user_id, 
      BeforeAfterPartitionId 
      ORDER BY 
        date ROWS BETWEEN UNBOUNDED PRECEDING 
        AND CURRENT ROW
    ) as sched_sum 
  FROM 
    CTE_PART
), 
CTE_PRIORS AS (
  SELECT 
    user_id, 
    date, 
    SUM(actual_sum) as PRIORS 
  FROM 
    CTE_CUMULATIVE 
  WHERE 
    date = '2022-06-06' 
  GROUP BY 
    user_id, 
    date
) 
SELECT 
  A.user_id, 
  A.date, 
  A.actual, 
  A.scheduled, 
  case when A.beforeafterpartitionId = 'Before' THEN A.actual_sum ELSE A.sched_sum + coalesce(B.PRIORS, 0) END as want 
FROM 
  CTE_CUMULATIVE A 
  LEFT OUTER JOIN CTE_PRIORS B ON A.user_id = B.user_id 
  AND A.date >= B.date 
ORDER BY 
  user_id, 
  date;

http://sqlfiddle.com/#!15/bef30/14

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文