MYSQL获取按用户分组的第一个(最小)和最后一个(最大)订单记录

MYSQL获取按用户分组的第一个(最小)和最后一个(最大)订单记录,mysql,Mysql,我有一个mysql表,存储所有客户订单,如下所示(问题简化): 在一个查询中,我希望获得每个用户的第一个订单和订单总数,以及他们最近的订单和订单总数 所以我应该得到如下结果: +----------+------------------+---------------+------------------+---------------+ | cust_id | first_ord_total | first_ord_date| last_ord_total | last_ord_dat

我有一个mysql表,存储所有客户订单,如下所示(问题简化):

在一个查询中,我希望获得每个用户的第一个订单和订单总数,以及他们最近的订单和订单总数

所以我应该得到如下结果:

+----------+------------------+---------------+------------------+---------------+
| cust_id  | first_ord_total  | first_ord_date| last_ord_total   | last_ord_date |
+----------+------------------+---------------+------------------+---------------+
| 123      | 150.48           | 2018-03-01    | 742.25           | 2020-05-19    |
| 456      | 20.99            | 2019-08-01    | 67.22            | 2020-09-17    | 
| 789      | 259.99           | 2019-01-01    | 147.15           | 2020-08-31    | 
+----------+------------------+---------------+------------------+---------------+
我似乎能够使用MIN和MAX获得第一个和最后一个订单日期,但我无法将其链接回去,也无法给出同一订单/记录的订单总数


我知道这是可能的,但我正在努力在MySQL 8+上正确地实现它,
行数
在这里派上了用场:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY created) rn_first,
              ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY created DESC) rn_last
    FROM orders
)

SELECT
    cust_id,
    MAX(CASE WHEN rn_first = 1 THEN total END)   AS first_ord_total,
    MAX(CASE WHEN rn_first = 1 THEN created END) AS first_ord_date,
    MAX(CASE WHEN rn_last = 1  THEN total END)   AS last_ord_total,
    MAX(CASE WHEN rn_last = 1  THEN created END) AS last_ord_date
FROM cte
GROUP BY
    cust_id;

这里的策略是针对每个客户使用
行编号
,以识别CTE中的第一个和最后一个交易记录。然后,我们按客户汇总,以找到第一个和最后一个总金额和日期。

如果您的MySql版本支持窗口函数,则使用MIN()、MAX()和first_VALUE()

在没有窗口函数的情况下,使用一个查询,该查询将重新键入每个客户的第一个和最后一个订单日期,并将其加入到使用条件聚合的表中:

select c.cust_id,
       max(case when c.created = t.min_created then c.total end) first_order_total,
       max(case when c.created = t.min_created then c.created end) first_order_date,
       max(case when c.created = t.max_created then c.total end) last_order_total,
       max(case when c.created = t.max_created then c.created end) last_order_date
from customers c 
inner join (
  select cust_id, min(created) min_created, max(created) max_created
  from customers
  group by cust_id  
) t on t.cust_id = c.cust_id and c.created in (t.min_created, t.max_created)
group by c.cust_id

有趣的是,我应该提到我现在被限制在5.7.12
select distinct cust_id,
       first_value(total) over (partition by cust_id order by created) first_order_total,
       min(created) over (partition by cust_id) first_order_date,
       first_value(total) over (partition by cust_id order by created desc) last_order_total,
       max(created) over (partition by cust_id) last_order_date
from customers
select c.cust_id,
       max(case when c.created = t.min_created then c.total end) first_order_total,
       max(case when c.created = t.min_created then c.created end) first_order_date,
       max(case when c.created = t.max_created then c.total end) last_order_total,
       max(case when c.created = t.max_created then c.created end) last_order_date
from customers c 
inner join (
  select cust_id, min(created) min_created, max(created) max_created
  from customers
  group by cust_id  
) t on t.cust_id = c.cust_id and c.created in (t.min_created, t.max_created)
group by c.cust_id