我有多个客户。他们中的一些只做了一次交易,而其他人做了更多。我想运行一个查询,帮助我了解每个客户的前两个交易,他们的时间戳和花费的金额。为此,我使用以下查询:
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)
我只想获得特定类型的交易(=='购买'),我想只获得前两笔交易。
查询正常运行,但仅适用于至少进行两次交易的客户。如果客户只进行了一次交易,他就不会出现在结果中。有没有办法修复查询,以便对于没有进行第二次交易的客户,我会得到与第二次交易相关的列的空白?
答案 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;