基于重复值场景的SQL数据筛选:按条件选取最小/最大值
问题描述
需要编写SQL语句从sold_out表中按以下条件筛选数据:
- 分组字段:
location_cd、machine_cd、product_cd、temperature; - 若分组内有多条记录的
MAX(created_timestamp)值相同,则选取data_source最小的行; - 其余情况直接选取
created_timestamp最大的行。
示例数据
| location_cd | machine_cd | product_cd | temperature | data_source | created_timestamp |
|---|---|---|---|---|---|
| 0012345678 | 1234567890 | 123456 | 1 | 3 | 2024/06/10 15:30:15 |
| 0012345678 | 1234567890 | 123456 | 1 | 4 | 2024/06/10 15:30:15 |
| 0012345678 | 1234567890 | 654321 | 0 | 3 | 2024/06/10 14:50:15 |
| 0012345678 | 1234567890 | 654321 | 0 | 4 | 2024/06/10 15:00:15 |
预期输出
| location_cd | machine_cd | product_cd | temperature | data_source | created_timestamp |
|---|---|---|---|---|---|
| 0012345678 | 1234567890 | 123456 | 1 | 3 | 2024/06/10 15:30:15 |
| 0012345678 | 1234567890 | 654321 | 0 | 4 | 2024/06/10 15:00:15 |
尝试的SQL(未得到正确结果)
SELECT machine_cd, location_cd, product_cd, temperature, case WHEN exists( SELECT machine_cd, location_cd, product_cd, temperature, created_timestamp, COUNT(*) From sold_out group by machine_cd, location_cd, product_cd, temperature, created_timestamp HAVING COUNT(*) > 1 ) THEN MIN(data_source) ELSE MAX(created_timestamp) END FROM sold_out GROUP BY machine_cd, location_cd, product_cd, temperature
解决方案
你之前的SQL存在两个核心问题:一是EXISTS判断的是全局是否存在重复时间的分组,而非当前分组内的情况;二是CASE分支返回的字段类型不匹配(一个是数值型的data_source,一个是时间型的created_timestamp),逻辑完全不符合需求。
可以用窗口函数ROW_NUMBER()实现需求,按指定分组字段分区,先按created_timestamp降序排序,再按data_source升序排序,取每个分区的第一行即可:
SELECT location_cd, machine_cd, product_cd, temperature, data_source, created_timestamp FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY location_cd, machine_cd, product_cd, temperature ORDER BY created_timestamp DESC, data_source ASC ) AS rn FROM sold_out ) t WHERE rn = 1;
逻辑说明
PARTITION BY指定分组字段,将数据按要求拆分为不同分组;ORDER BY先按created_timestamp降序,确保最新时间的记录排在前面;若时间相同,再按data_source升序,让data_source最小的记录排在首位;- 外层查询筛选
rn=1的记录,即为每个分组内符合要求的目标行。
这个逻辑完全匹配你的需求:
- 对于
product_cd=123456的分组,两条记录时间相同,data_source=3的记录被选中; - 对于
product_cd=654321的分组,created_timestamp最大的记录被选中。
内容的提问来源于stack exchange,提问作者ninh_nguyen
相关产品推荐
相关产品推荐

