我的数据如下:
Table Name = sales_orders
Customer_id| Order_id| Item_Id
-------------------------------
1 | 1 | 10
1 | 1 | 24
1 | 1 | 37
1 | 2 | 11
1 | 2 | 15
1 | 3 | 28
2 | 4 | 37
4 | 6 | 10
2 | 7 | 10
但是,我需要它看起来像这样:
Customer_id| Order_id| Item_Id |Order_rank
------------------------------------------
1 | 1 | 10 | 1
1 | 1 | 24 | 1
1 | 1 | 37 | 1
1 | 2 | 11 | 2
1 | 2 | 15 | 2
1 | 3 | 28 | 3
2 | 4 | 37 | 1
4 | 6 | 10 | 1
2 | 7 | 10 | 2
Customer_Id是唯一的人
Order_id是唯一的订单
item_id是产品代码
为进一步说明,前三行来自客户#1的第一笔订单(order_id = 1),此人订购了3种不同的商品(10、24和37)。然后,他们与另外两个产品一起购买了另一个订单(order_id = 2)。 customer_id = 2的人有2个唯一订单(4和6),而ID为“ 4”的客户有1个唯一订单(order_id = 6)
本质上,我需要做的是按customer_id和订单ID对这些订单进行排名,这样我可以说“ Order_id = 7是customer_id = 2的第二个订单,因为Order_rank = 2”
这里的挑战是我不能在MySQL查询中使用会话变量(例如@grp:= customer_id)
例如,不允许进行这样的查询:
SELECT
customer_id,
order_id,
@ss := CASE WHEN @grp = customer_id THEN @ss + 1 ELSE 1 END AS
order_rank,
@grp := customer_id
FROM
(
SELECT
customer_id,
order_id
FROM sales_orders
GROUP BY customer_id, order_id
ORDER BY customer_id, order_id ASC
) AS t_1
CROSS JOIN (SELECT @ss := 0, @grp = NULL)ss
ORDER BY customer_id asc
感谢您的帮助!
答案 0 :(得分:3)
在Correlated Subquery中,我们可以Count(..)
为特定行的order_id
和customer_id
的唯一的和先前的 order_id
值确定排名。
我们需要计算唯一值,因为每个订单有多行(由于有多个项目)。
查询
SELECT
t1.Customer_id,
t1.Order_id,
t1.Item_Id,
(SELECT COUNT(DISTINCT t2.Order_id)
FROM sales_orders t2
WHERE t2.Customer_id = t1.Customer_id AND
t2.Order_id <= t1.Order_id
) AS Order_rank
FROM sales_orders AS t1;
结果
| Customer_id | Order_id | Item_Id | Order_rank |
| ----------- | -------- | ------- | ---------- |
| 1 | 1 | 10 | 1 |
| 1 | 1 | 24 | 1 |
| 1 | 1 | 37 | 1 |
| 1 | 2 | 11 | 2 |
| 1 | 2 | 15 | 2 |
| 1 | 3 | 28 | 3 |
| 2 | 4 | 37 | 1 |
| 4 | 6 | 10 | 1 |
| 2 | 7 | 10 | 2 |
答案 1 :(得分:0)
您可以使用相关子查询:
select so.*,
(select count(*)
from sales_orders so2
where so2.Customer_id = so.Customer_id and
so2.order_id <= so.order_id
) as rank_order
from sales_orders so;
或者在MySQL 8+中:
select so.*,
dense_rank() over (partition by Customer_Id order by Order_Id) as rank_order
from sales_orders so;