简体   繁体   English

计算合并到 PostgreSQL 中单个列的特定“日期”的累积和

[英]Calculating the cumulative sum with a specific 'date' merged to single column in PostgreSQL

I have a database which contains the amounts and dates per user paid.我有一个数据库,其中包含每个用户支付的金额和日期。 Now some users make payments on the same day and I want to show the cumulative sum of these payments only once per day in a pivot table, which I am creating using Amazon QuickSight.现在一些用户在同一天付款,我想在我使用 Amazon QuickSight 创建的 pivot 表中每天只显示一次这些付款的累积总和。

I have gone through the following, but they provide the cumulative values once per row and I don't have a way to partition on just the date and not on anything else, with the sum over the payment made.我已经完成了以下操作,但是它们每行提供一次累积值,我没有办法仅在日期而不是其他任何东西上进行分区,总和超过已付款。

Calculating Cumulative Sum in PostgreSQL 计算 PostgreSQL 中的累计和

Calculating cumulative sum with date filtering in PostgreSQL 在 PostgreSQL 中使用日期过滤计算累积和

Calculating Cumulative daily sum in PostgreSQL 计算 PostgreSQL 中的累计每日总和

PostgreSQL, renumber and cumulative sum at once PostgreSQL,一次重新编号和累计和

How to conditional sum two columns in PostgreSQL 9.3 如何对 PostgreSQL 9.3 中的两列进行条件求和

My query looks like this:我的查询如下所示:

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

Where I am doing a Sum() Over() at this row:我在这一行做 Sum() Over() 的地方:

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

My Table has data as:我的表的数据如下:

Users:用户:

| 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    |

Payments:付款:

| 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 |

The output I want is that the "Daily Amount" is shown only once for a specific date, if there are multiple rows with the same date, then for the other rows, it should be blank or display something like "NA":我想要的 output 是“每日金额”仅在特定日期显示一次,如果有多个具有相同日期的行,那么对于其他行,它应该为空白或显示类似“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         |   

Is there some way that it is possible to get this output from SQL (PostgreSQL specific query)?有什么方法可以从 SQL (PostgreSQL 特定查询)获得这个 output 吗?

Looks like your sum() over() computes the wrong amount, try看起来你的sum() over()计算了错误的数量,试试

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

EDIT If you want to format output (cumulative amount only once per date), use row_number() to detect first row in a group.编辑如果要格式化 output (每个日期仅累积一次),请使用row_number()检测组中的第一行。 Make sure over() clause is in sync with ORDER BY of the query.确保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

If you want the value only once per date, then use row_number() :如果您希望每个日期仅使用一次该值,请使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM