【问题标题】:Calculating the cumulative sum with a specific 'date' merged to single column in PostgreSQL计算合并到 PostgreSQL 中单个列的特定“日期”的累积总和
【发布时间】:2021-08-19 08:28:11
【问题描述】:

我有一个数据库,其中包含每位用户支付的金额和日期。现在一些用户在同一天付款,我想在我使用 Amazon QuickSight 创建的数据透视表中每天只显示一次这些付款的累积总和。

我已经完成了以下操作,但它们每行提供一次累积值,我无法仅根据日期而不是其他任何内容进行分区,总和超过已付款。

Calculating Cumulative Sum in PostgreSQL

Calculating cumulative sum with date filtering in PostgreSQL

Calculating Cumulative daily sum in PostgreSQL

PostgreSQL, renumber and cumulative sum at once

How to conditional sum two columns in PostgreSQL 9.3

我的查询如下所示:

SELECT
    s.id,
    s.first_name,
    s.last_name,
    s.birth_date,
    s.card,
    p.datetime,
    p.amount,
    Sum(p.amount)OVER(partition BY p.datetime ORDER BY p.datetime ) AS "Daily Amount"

FROM payments AS p

LEFT JOIN users AS s
ON p.s_h_uuid = s.h_uuid

ORDER BY p.datetime DESC

我在这一行做 Sum() Over():

Sum(pa.amount)OVER(partition BY p.datetime ORDER BY p.datetime ) AS "Daily Amount"

我的表的数据为:

用户:

| id | first_name | last_name | birth_date | card |
| 2  | first_nam2 | last_nam2 | 1990-02-01 | M    |
| 3  | first_nam3 | last_nam3 | 1987-07-23 | M    |
| 1  | first_nam1 | last_nam1 | 1954-11-15 | A    |
| 4  | first_nam4 | last_nam4 | 1968-05-07 | V    |

付款:

| p_uuid | datetime   | amount |
| 2      | 2021-05-01 | 100.00 |
| 3      | 2021-05-01 | 100.00 |
| 2      | 2021-05-02 | 100.00 |
| 1      | 2021-05-03 | 100.00 |
| 3      | 2021-05-03 | 100.00 |
| 4      | 2021-05-03 | 100.00 |
| 2      | 2021-05-05 | 100.00 |
| 1      | 2021-05-05 | 100.00 |
| 4      | 2021-05-06 | 100.00 |

我想要的输出是“每日金额”在特定日期仅显示一次,如果有多个具有相同日期的行,那么对于其他行,它应该为空白或显示类似“NA”的内容:

| p.datetime | id | first_name | last_name | birth_date | card | pa.amount | "Daily Amount" |
| 2021-05-01 | 2  | first_nam2 | last_nam2 | 1990-02-01 | M    | 100.00    | 200.00         |
| 2021-05-01 | 3  | first_nam3 | last_nam3 | 1987-07-23 | M    | 100.00    |                |
| 2021-05-02 | 2  | first_nam2 | last_nam2 | 1990-02-01 | M    | 100.00    | 100.00         |
| 2021-05-03 | 1  | first_nam1 | last_nam1 | 1954-11-15 | A    | 100.00    | 300.00         |   
| 2021-05-03 | 3  | first_nam3 | last_nam3 | 1987-07-23 | M    | 100.00    |                |
| 2021-05-03 | 4  | first_nam4 | last_nam4 | 1968-05-07 | V    | 100.00    |                |
| 2021-05-05 | 2  | first_nam2 | last_nam2 | 1990-02-01 | M    | 100.00    | 200.00         |
| 2021-05-05 | 1  | first_nam1 | last_nam1 | 1954-11-15 | A    | 100.00    |                |
| 2021-05-06 | 4  | first_nam4 | last_nam4 | 1968-05-07 | V    | 100.00    | 100.00         |   

是否可以通过某种方式从 SQL(PostgreSQL 特定查询)获取此输出?

【问题讨论】:

  • 轻松为您提供帮助 - 简化! minimal reproducible example
  • 我提供了在给定日期输出的不同方式,因此输出中有 9 行。我放了更少的行,但是上下文消失了。

标签: sql postgresql where-clause amazon-quicksight


【解决方案1】:

如果您只需要每个日期一次的值,请使用row_number()

select (case when 1 = row_number() over (partition by p.date order by p.p_uuid)
             then sum(p.amount) over (partition by p.date)
        end) as day_payments

【讨论】:

    【解决方案2】:

    看起来您的 sum() over() 计算的金额有误,请尝试

     Sum(p.amount) OVER(partition BY s.id, p.datetime) AS "Daily Amount",
    

    编辑 如果要格式化输出(每个日期仅累积一次),请使用 row_number() 检测组中的第一行。确保over() 子句与查询的ORDER BY 同步。

    SELECT 
            id,
            first_name,
            last_name,
            birth_date,
            card,
            datetime,
            amount,
            case when rn=1 then "Daily Amount" end "Daily Amount" 
    FROM (
        SELECT
            s.id,
            s.first_name,
            s.last_name,
            s.birth_date,
            s.card,
            p.datetime,
            p.amount,
            Sum(p.amount) OVER(partition BY s.id, p.datetime) AS "Daily Amount",
            row_number() OVER(partition BY s.id, p.datetime ORDER BY p.amount) AS rn
        FROM payments AS p
        LEFT JOIN users AS s ON p.s_h_uuid = s.h_uuid
    ) t
    ORDER BY datetime DESC, id, amount
    

    【讨论】:

    • 感谢您的回答,但它仍会为每行显示一次金额。我想避免它在同一个“日期”中多次显示。因此,期望的输出是将其显示为每个日期仅一次的累积量。如果日期出现在另一列中,我希望“每日金额”为空白或其他值,如“NA”
    • 那么首先您需要在查询中使用更具体的ORDER BY 来定义输出中的行顺序。例如 ORDER BY s.id, p.datetime, p.amount 。并使用它来计算 row_number () 并仅显示第一个数量。输出中所需的行顺序是什么?
    • 好的,将尝试使用 ORDER BY 子句中的元组。我想要的顺序是日期字段。我正在查看 IF 和 WHERE 子句,但无法使用它们制定所需的 SQL,因为查询是逐行的,对于我想要的,它可能需要生成整个查询,然后生成一个子查询,它采用所需的列并以这种方式对其进行排序?
    • 非常感谢。我认为,当我们查看日期时,只需将日期时间转换为 date() 即可,如果时间不同,它将再次以新的 'rn' 开始。
    猜你喜欢
    • 1970-01-01
    • 2018-07-21
    • 2021-05-13
    • 2018-06-05
    • 2021-06-07
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    相关资源
    最近更新 更多