我正在try 向我的查询中添加两个窗口函数.一个是计算每个客户的滚动总数,另一个是简单地添加每个客户的行号.

当滚动总和运行得很好时,行号不会正确排序.我想添加一个降序行号,这样我就可以保留每个客户的所有行号1,我想在其中找到该客户的总和.

我在Snowflake SQL工作.

CREATE TABLE transactions (
    customer_id INTEGER
    ,txn_date DATE
    ,txn_type VARCHAR(10)
    ,txn_amount INTEGER
);

INSERT INTO transactions (customer_id, txn_date, txn_type, txn_amount) 
VALUES
('1', '2020-01-02', 'deposit',  '312'),
('1', '2020-01-02', 'deposit', '312'),
('1', '2020-03-05', 'purchase', '612'), 
('1', '2020-03-05', 'purchase', '612'), 
('1', '2020-03-17', 'deposit', '324'),  
('1', '2020-03-17', 'deposit', '324'),
('1', '2020-03-19', 'purchase', '664'), 
('1', '2020-03-19', 'purchase', '664');

这是我目前使用的查询:

SELECT 
  customer_id
  ,txn_type
  ,txn_date
  ,txn_amount
  ,CASE WHEN txn_type = 'deposit'
        THEN txn_amount
        ELSE txn_amount * -1
   END AS new_amount
  ,SUM(new_amount) OVER (
   PARTITION BY customer_id
   ORDER BY customer_id, txn_date
   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
  ,ROW_NUMBER() OVER (
   PARTITION BY customer_id
   ORDER BY customer_id, txn_date DESC) AS rn
FROM
  transactions
ORDER BY
  customer_id
  ,txn_date;

它给我带来了这些结果:

customer_id txn_type txn_date txn_amount new_amount running_total rn
1 deposit 2020-01-02 312 312 312 7
1 deposit 2020-01-02 312 312 624 8
1 purchase 2020-03-05 612 -612 12 5
1 purchase 2020-03-05 612 -612 -600 6
1 deposit 2020-03-17 324 324 -276 3
1 deposit 2020-03-17 324 324 48 4
1 purchase 2020-03-19 664 -664 -616 1
1 purchase 2020-03-19 664 -664 -1280 2

虽然我预计会是这样的:

customer_id txn_type txn_date txn_amount new_amount running_total rn
1 deposit 2020-01-02 312 312 312 8
1 deposit 2020-01-02 312 312 624 7
1 purchase 2020-03-05 612 -612 12 6
1 purchase 2020-03-05 612 -612 -600 5
1 deposit 2020-03-17 324 324 -276 4
1 deposit 2020-03-17 324 324 48 3
1 purchase 2020-03-19 664 -664 -616 2
1 purchase 2020-03-19 664 -664 -1280 1

那么我到底做错了什么呢?

最后,我不仅要按客户ID划分行号,还要按月划分行号,这样我就可以获取每个月的最新记录,并查看Running_Total是多少.

推荐答案

因为您有重复的数据,所以会得到不一致的结果.下面是在CTE中创建伪事务id,然后在主查询的第二个窗口函数中引用该伪id的方法.

with cte as (
 select 
  customer_id
  ,txn_type
  ,txn_date
  ,txn_amount
  ,CASE WHEN txn_type = 'deposit'
        THEN txn_amount
        ELSE txn_amount * -1
   END AS new_amount
  ,ROW_NUMBER() over (
   partition by customer_id 
   order by customer_id, txn_date) as trans_id
  from transactions
)
select 
 customer_id 
 ,txn_type
 ,txn_date
 ,txn_amount
 ,new_amount
 ,SUM(new_amount) OVER (
   PARTITION BY customer_id
   ORDER BY customer_id, txn_date
   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
 ,ROW_NUMBER() OVER (
   PARTITION BY customer_id
   ORDER BY customer_id, trans_id DESC) AS rn
from cte
order by 
 customer_id, 
 rn desc;

输出:

CUSTOMER_ID TXN_TYPE TXN_DATE TXN_AMOUNT NEW_AMOUNT RUNNING_TOTAL RN
1 deposit 2020-01-02 312 312 312 8
1 deposit 2020-01-02 312 312 624 7
1 purchase 2020-03-05 612 -612 12 6
1 purchase 2020-03-05 612 -612 -600 5
1 deposit 2020-03-17 324 324 -276 4
1 deposit 2020-03-17 324 324 48 3
1 purchase 2020-03-19 664 -664 -616 2
1 purchase 2020-03-19 664 -664 -1280 1

如果这是您想要的路由,那么您可以使用以下内容来简单地使用主查询来计算运行总和,因为您不再需要担心重复项:

,SUM(new_amount) OVER (
 PARTITION BY customer_id
 ORDER BY customer_id, trans_id) AS running_total

Sql相关问答推荐

查询将查找将标记设置为user2的用户

为什么Postgrs Planner会在输出部分中显示我在查询中不使用的列?'""

基于前面行的值:当x&>2时重复1,当连续3行x=0时则重复0

如何根据特定的内部json元素值过滤postgres查询结果?

通过之前的连接-这是Oracle的错误吗?

查询每周数据(周一至周日),避免年度日期重叠

将Dense_RANK列为聚合(非解析)函数(&A)

IF NOT EXISTS子查询的性能瓶颈

如何将不同层次的产品组和规格组合到最深一层?

在Power Bi中将SQL代码转换为DAX

使用递归CTE在BigQuery中获取文件路径

SQL中相同表内的VLOOKUP等价

如何在Hive SQL中分别按多列进行分组?

如何使用最后一个非 NULL 值在 PostgreSQL 列中填充 NULL 值

Spark / Hive:如何获取列中正值的百分比?

使用ALTER TABLE无法删除列

根据是否存在值组合分组并 Select 行

使用一组值进行分组和计数

在时态表和非时态表之间使用 EXCEPT 的 SQL 子查询给出表达式错误数

在 SQL 中将行显示为列