LEAD功能,某些记录没有下一个事务

时间:2017-11-02 08:57:11

标签: sql postgresql

我有多个客户。他们中的一些只做了一次交易,而其他人做了更多。我想运行一个查询,帮助我了解每个客户的前两个交易,他们的时间戳和花费的金额。为此,我使用以下查询:

select t.* 
from 
  (select customer_id, 
    transaction_type as tx_0, 
    transaction_timestamp as tx_0_time, amount as tx_0_amount,
    lead(transaction_type, 1) over (partition by customer_id order by transaction_timestamp) as tx_1,
    lead(transaction_timestamp, 1) over (partition by customer_id order by transaction_timestamp) as tx_1_time
    lead(amount, 1) over (partition by customer_id order by transaction_timestamp) as tx_1_amount,
  from payment_table 
  ) t
right join 
  (select customer_id, min(transaction_timestamp) as minimal
  from payment_table
  where transaction_type = 'Buy'
  group by customer_id) s
on t.customer_id = s.customer_id and t.tx_0_time = s.minimal
where tx_0 = 'Buy'
and tx_1 in ('Buy', '', null)

我只想获得特定类型的交易(=='购买'),我想只获得前两笔交易。

查询正常运行,但仅适用于至少进行两次交易的客户。如果客户只进行了一次交易,他就不会出现在结果中。有没有办法修复查询,以便对于没有进行第二次交易的客户,我会得到与第二次交易相关的列的空白?

3 个答案:

答案 0 :(得分:1)

t.tx_1中的所有NULL都将被您的第二个WHERE条件过滤掉。

请记住,NULL的行为与其他值不同,NULL IN ('Buy', '', null)将导致NULL而不是TRUE。

您应该将该条件重写为

(t.tx_1 IS NULL OR t.tx_1 = 'Buy')

或更简洁,但也更隐秘,

coalesce(t.tx_1, 'Buy') = 'Buy'

或者,将比较移至连接条件!

答案 1 :(得分:0)

NULL中的IN与任何内容都不匹配,因此这是一个问题。但是,您正在执行JOIN,其中没有必要:

select distinct on (customer_id) t.* 
from (select customer_id, 
             transaction_type as tx_0, 
             transaction_timestamp as tx_0_time,
             amount as tx_0_amount,
             lead(transaction_type, 1) over (partition by customer_id order by transaction_timestamp) as tx_1,
             lead(transaction_timestamp, 1) over (partition by customer_id order by transaction_timestamp) as tx_1_time
             lead(amount, 1) over (partition by customer_id order by transaction_timestamp) as tx_1_amount
      from payment_table 
     ) t
where tx_0 = 'Buy' and (tx_1 = 'Buy' or tx_1 is null)
order by customer_id, tx_0_time;

答案 2 :(得分:0)

无需加入,您可以使用ROW_NUMBER过滤每个客户的第一行。此外,您不需要在最终结果中包含transaction_type任何一项交易,您只需对其进行过滤即可,因为您只对Buy次交易感兴趣。

SELECT customer_id, tx_0_time, tx_0_amount, tx_1_time, tx_1_amount
FROM 
  (SELECT
     customer_id,
     transaction_timestamp AS tx_0_time,
     amount AS tx_0_amount,
     lead(transaction_timestamp, 1)
       OVER (PARTITION BY customer_id ORDER BY transaction_timestamp)
       AS tx_1_time,
     lead(amount, 1)
       OVER (PARTITION BY customer_id ORDER BY transaction_timestamp)
       AS tx_1_amount,
     row_number()
       OVER (PARTITION BY customer_id ORDER BY transaction_timestamp)
       AS rn
   FROM payment_table
   WHERE transaction_type = 'Buy'
  ) t
WHERE rn = 1;