基于is_available字段筛选指定product_id最新记录的MySQL查询需求
问题描述
现有如下数据表:
| id | date | is_available | product_id | product_recalled |
|---|---|---|---|---|
| 200 | 2019-10-10 | 1 | 123 | yes |
| 201 | 2020-07-10 | 1 | 123 | no |
| 202 | 2020-08-11 | 0 | 123 | yes |
| 203 | 2021-07-10 | 0 | 123 | yes |
| 204 | 2021-01-10 | 0 | 123 | no |
| 205 | 2021-07-10 | 0 | 124 | yes |
| 206 | 2021-01-10 | 0 | 124 | no |
需要编写单条MySQL查询语句,针对指定product_id筛选符合以下规则的最新记录:
- 若该
product_id同时存在is_available=1和is_available=0的记录,获取is_available=1中的最新记录(如product_id=123的场景) - 若该
product_id仅存在is_available=0的记录,获取is_available=0中的最新记录(如product_id=124的场景)
预期输出示例
示例1:指定product_id=123
| id | date | is_available | product_id | product_recalled |
|---|---|---|---|---|
| 201 | 2020-07-10 | 1 | 123 | no |
示例2:指定product_id=124
| id | date | is_available | product_id | product_recalled |
|---|---|---|---|---|
| 205 | 2021-07-10 | 0 | 124 | yes |
解决方案
以下是两种符合需求的MySQL查询写法:
写法一:用窗口函数实现优先级排序
SELECT id, date, is_available, product_id, product_recalled FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY product_id ORDER BY is_available DESC, date DESC ) AS rn FROM your_table_name WHERE product_id = 123 -- 替换为目标product_id ) t WHERE rn = 1;
逻辑说明
- 内层查询通过
ROW_NUMBER()窗口函数,对指定product_id的记录先按is_available降序排列(让is_available=1的记录优先级更高),再按date降序排列(同状态下最新记录排在最前)。 - 外层查询取排名为1的记录,直接匹配需求:有
is_available=1的记录时优先取该状态的最新值,无则取is_available=0的最新值。
写法二:用条件判断筛选目标状态
SELECT id, date, is_available, product_id, product_recalled FROM your_table_name WHERE product_id = 124 -- 替换为目标product_id AND is_available = ( CASE WHEN EXISTS (SELECT 1 FROM your_table_name WHERE product_id = 124 AND is_available = 1) THEN 1 ELSE 0 END ) ORDER BY date DESC LIMIT 1;
逻辑说明
- 子查询通过
EXISTS判断指定product_id是否存在is_available=1的记录,返回对应的目标状态值。 - 主查询筛选该状态下的所有记录,按日期降序后取第一条,即为该状态的最新记录。
注意:将上述语句中的your_table_name替换为实际数据表名,product_id的数值替换为目标值即可。
内容的提问来源于stack exchange,提问作者user3376592
相关产品推荐
相关产品推荐

