我正在处理一个名为orders
的Postgres表,它看起来像这样:
user_id product order_date
1 pants 7/1/2022
2 shirt 6/1/2022
1 socks 3/17/2023
3 pants 2/17/2023
4 shirt 3/13/2023
2 pants 8/15/2022
1 hat 4/15/2022
5 hat 3/14/2023
2 socks 12/3/2022
3 shirt 4/15/2023
4 socks 1/15/2023
4 pants 4/19/2023
5 shirt 5/2/2023
5 belt 5/15/2023
下面是一个dB Fiddle的数据:https://www.db-fiddle.com/f/uNGjP7gpKwdPGrJ7XmT7k3/2
我输出了一个表,显示了客户订单的 * 序列 *:
user_id first_order second_order third_order
1 hat pants socks
2 shirt pants socks
3 pants shirt <null>
4 socks shirt pants
5 hat shirt belt
例如,顾客1首先购买了帽子,然后购买了裤子,最后购买了袜子。
我想在行级别设置某种指示器,告诉我特定客户是否在购买另一个产品之前购买了一个产品。例如,我想指出客户是否在购买裤子之前购买了衬衫。
所需的输出如下所示:
user_id first_order second_order third_order shirt_before_pants
1 hat pants socks false
2 shirt pants socks true
3 pants shirt <null> false
4 socks shirt pants true
5 hat shirt belt false
有没有一种方法可以在行级别获得给定值的相对位置?
谢谢你的帮助…-瑞秋
4条答案
按热度按时间bejyjqdl1#
我们可以使用
row_number()
枚举每个客户的订单,然后使用条件聚合生成新列。要检查一个产品是否在另一个之前购买,我们可以比较两个产品的最小订单日期:e0bqpujr2#
如果...
fiddle
它的美妙之处:只更改
LIMIT
为不同数量的订单在您的请求。只在一个地方换裤子和衬衫。由于子查询中的排序,输出数组中的产品已排序。参见:
如果您在
orders(user_id, order_date)
或更好的orders(user_id, order_date) INCLUDE (product)
上有一个索引,那么对于每个用户有 * 许多 * 订单的大表,查询性能良好。如果你没有
users
表(你应该有一个),可以这样创建:或者在这里阅读更快的方法:
nvbavucw3#
此方法使用窗口函数
ROW_NUMBER
(DENSE_RANK也可以工作),它为user_id聚合的每一行分配一个行号。为了确定衬衫是否是在裤子之前购买的,我们可以比较这些产品的生成的 row_ids:omvjsjqw4#
array_position
函数在这里可能会有帮助:或者,以下方法也可以: