SQL多MIN()函数优先级疑问:SELECT子句中MIN()顺序是否影响结果?
问题解答
1. SELECT子句中MIN()的顺序是否重要?
完全不重要。SELECT里的列顺序只决定最终结果集里列的显示位置,不会影响每个聚合函数(比如MIN)的计算逻辑。不管你把MIN(DATE)放在MIN(LOC_NO)前面还是后面,两个函数都是各自独立对分组内的对应列取最小值,计算结果不会变,只是结果里列的顺序调换而已。
2. 你当前写法的问题
你现在的查询逻辑是:对每个PART_NO分组,分别取组内最早的DATE,和组内最小的LOC_NO——这两个值可能来自分组里的不同行,所以才会出现你不想看到的结果。比如示例数据里,最早DATE对应的LOC_NO可能不是组内最小的,而你的查询把这两个独立的最小值拼在了一起,导致得到错误的行。
3. 正确的写法
要获取最早DATE对应的那一行的LOC_NO,你需要把MIN(DATE)作为条件,找到对应的行,而不是单独取MIN(LOC_NO)。这里提供两种常见写法:
写法一:用子查询关联
SELECT t.PART_NO, t.DATE, t.LOC_NO FROM your_table t INNER JOIN ( SELECT PART_NO, MIN(DATE) AS min_date FROM your_table GROUP BY PART_NO ) t_min ON t.PART_NO = t_min.PART_NO AND t.DATE = t_min.min_date
这个写法先找到每个PART_NO的最早日期,再关联原表找到对应行的LOC_NO。如果同一个PART_NO有多个行是最早DATE,会返回所有这些行;如果只需要其中一个LOC_NO,可以加LIMIT 1或者再聚合。
写法二:用窗口函数(推荐)
SELECT PART_NO, DATE, LOC_NO FROM ( SELECT PART_NO, DATE, LOC_NO, ROW_NUMBER() OVER (PARTITION BY PART_NO ORDER BY DATE ASC) AS rn FROM your_table ) t WHERE rn = 1
窗口函数ROW_NUMBER()会给每个PART_NO分组内的行按DATE升序编号,最早的DATE对应的行编号是1,筛选出rn=1的行就是你要的结果。同样,如果有多个行DATE相同,只会返回其中一行;如果要保留所有相同最早DATE的行,把ROW_NUMBER()换成RANK()即可。
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

