求助编写MySQL多表关联语句,获取客户最新订阅信息
获取客户最新订阅信息的SQL查询
先明确你的表结构与现有数据:
现有表结构与数据
1. internetclient(客户表)
| id | full_name | location | phone_number |
|---|---|---|---|
| 4 | Joe Amine | beirut | 03776132 |
| 5 | Mariam zoue | beirut | 03556133 |
2. internetclientdetails(客户订阅详情表)
(注:incdid=internetClientDetailsId,icid=internetClientId)
| incdid | icid | date_sub | date_exp | isPaid | sub_price |
|---|---|---|---|---|---|
| 6 | 4 | 2018-01-01 | 2018-01-30 | 0 | 2000 |
| 7 | 5 | 2017-01-01 | 2017-01-30 | 0 | 1000 |
| 8 | 4 | 2018-03-01 | 2018-03-30 | 1 | 50000 |
| 9 | 5 | 2018-05-01 | 2019-05-30 | 1 | 90000 |
需求目标
根据客户的最新订阅日期,返回客户姓名、客户ID、订阅日期、订阅价格,预期结果如下(注:你预期里的Mary应为原数据的Mariam zoue):
------------------------------------------------------------ full_name client_id date_sub sub_price ------------------------------------------------------------ Joe Amine 4 2018-03-01 50000 Mariam zoue 5 2018-05-01 90000
你当前语句的问题
你的尝试语句存在几个明显问题:
- 语法错误:子查询缺少闭合的
),还引用了不存在的字段c.sub_date(客户表无此字段,应为订阅表的date_sub) - 逻辑冗余:
LEFT JOIN UNION RIGHT JOIN等价于全连接,但我们只需要关联有订阅记录的客户,完全没必要用全连接 - 逻辑错误:子查询分组后直接返回
MAX(sub_date),无法和外层记录对应关联,筛选不出每个客户的最新订阅记录
解决方案
这里提供两种常用的可行方案:
方案1:使用窗口函数(推荐,支持MySQL 8+、SQL Server、PostgreSQL等)
窗口函数ROW_NUMBER()可以按客户分组,对每个客户的订阅记录按日期倒序编号,取编号为1的记录就是最新订阅:
SELECT full_name, id AS client_id, date_sub, sub_price FROM ( SELECT c.full_name, c.id, cs.date_sub, cs.sub_price, -- 按客户分组,订阅日期倒序排序,给每条记录编号 ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY cs.date_sub DESC) AS rn FROM internetclient c INNER JOIN internetclientdetails cs ON c.id = cs.icid ) AS temp -- 只保留每个客户的第一条(最新)订阅记录 WHERE temp.rn = 1;
方案2:使用关联子查询(兼容旧版数据库)
如果你的数据库不支持窗口函数,可以用关联子查询先找到每个客户的最大订阅日期,再关联回订阅表获取对应价格:
SELECT c.full_name, c.id AS client_id, cs.date_sub, cs.sub_price FROM internetclient c INNER JOIN internetclientdetails cs ON c.id = cs.icid -- 筛选出当前客户的订阅日期等于该客户最大订阅日期的记录 WHERE cs.date_sub = ( SELECT MAX(date_sub) FROM internetclientdetails WHERE icid = c.id );
这两种方案都能得到你想要的预期结果,其中窗口函数方案更灵活——如果存在多个相同的最新订阅日期,还可以把ROW_NUMBER()换成RANK()来保留多条记录。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

