如何计算当前订单之前的订单数量

时间:2019-08-29 10:47:18

标签: mysql sql group-by aggregate-functions

我有订单表:

| order_id | buyer_id | order_created_at    |
|----------|----------|---------------------|
| 54       | 609      | 2018-08-11 16:46:53 |
| 74       | 363      | 2019-06-01 00:00:00 |
| 75       | 300      | 2019-06-01 00:00:02 |
| 76       | 609      | 2019-06-01 00:00:03 |

我想显示如下数据:

| order_id | buyer_id | Number_of_orders_plus_this_order |
|----------|----------|----------------------------------|
| 54       | 609      |                                2 |
| 74       | 363      |                                4 |
| 75       | 300      |                                7 |
| 76       | 609      |                                5 |

我尝试了两种方法,第一种:

select t1.order_id, orders.buyer_id, count(1) as Number_of_orders_plus_this_order
from (
 select buyer_id, order_created_at, order_id
 from orders o1
 where o1.order_id in (75, 74, 54,76)
) as t1
join orders on orders.buyer_id = t1.buyer_id
where orders.order_created_at <= t1.order_created_at
group by 1, 2

由于有一个买方(标识号:609)被显示两次,因此我按buyer_id分组,这将显示忽略他的一个订单的结果。 像这样:

| order_id | buyer_id | Number_of_orders_plus_this_order |
|----------|----------|----------------------------------|
| 54       | 609      |                                2 |
| 74       | 363      |                                4 |
| 75       | 300      |                                7 |

第二种方法是使用python,我为每个订单创建了一个循环并查询数据库。这当然要花很长时间,而且根本不实用。

3 个答案:

答案 0 :(得分:1)

您可以使用相关的子查询来做到这一点:

SELECT order_id, buyer_id, order_created_at, 1 + (
    SELECT COUNT(*)
    FROM orders AS x
    WHERE x.buyer_id = t.buyer_id
    AND (
        x.order_created_at < o.order_created_at OR (
            -- orders having same date need a tie breaker
            x.order_created_at = o.order_created_at
            AND x.order_id < o.order_id
        )
    )
) AS number_of_orders_plus_this_order
FROM orders AS t
WHERE order_id IN (75, 74, 54, 76)

答案 1 :(得分:0)

您是否只是尝试枚举订单,然后提取少量订单的枚举?如果是这样,请使用窗口功能:

select o.*
from (select o.*, row_number() over (order by order_created_at) as seqnum
      from orders o
     ) o
where o.order_id in (75, 74, 54, 76);

答案 2 :(得分:0)

您要显示特定的订单。对于其中的每一个,您都希望计算同一买家在此之前所下的订单。

您可以在select子句中使用子查询轻松地做到这一点:

select
  o.*,
  (
    select count(*)
    from orders o2
    where o2.buyer_id = o.buyer_id
      and o2.order_created_at <= o.order_created_at
  ) as num_of orders
from orders o
where order_id in (75, 74, 54, 76)
order by order_id;