如何获取最小Opened Date及所有Open状态记录(SQL Server)
解决方案(SQL Server)
首先创建测试数据(可直接运行验证):
CREATE TABLE YourTable ( Number INT, CI VARCHAR(10), PLUGIN VARCHAR(10), [Opened Date] DATE, State VARCHAR(10) ); INSERT INTO YourTable VALUES (1, 'XYZ', 'A123', '2023-01-01', 'Closed'), (2, 'XYZ', 'A123', '2023-02-01', 'Closed'), (3, 'XYZ', 'A123', '2023-03-01', 'Closed'), (4, 'XYZ', 'A123', '2023-04-01', 'Open'), (5, 'XYZ', 'A123', '2023-05-01', 'Open');
需求1:返回最旧记录 + 所有Open状态记录
方法1:UNION ALL 组合查询
分别筛选最小日期的记录和Open状态记录,用UNION ALL合并(比UNION高效,无需去重):
SELECT Number, CI, PLUGIN, [Opened Date], State FROM YourTable WHERE [Opened Date] = (SELECT MIN([Opened Date]) FROM YourTable) UNION ALL SELECT Number, CI, PLUGIN, [Opened Date], State FROM YourTable WHERE State = 'Open';
方法2:单查询OR过滤
直接在WHERE子句中用OR连接两个条件,子查询获取最小日期:
SELECT Number, CI, PLUGIN, [Opened Date], State FROM YourTable WHERE State = 'Open' OR [Opened Date] = (SELECT MIN([Opened Date]) FROM YourTable);
需求2:返回Open状态记录并新增最小Opened Date列
方法1:窗口函数(推荐)
用MIN() OVER()窗口函数,无需分组即可为每条Open记录添加全局最小日期:
SELECT Number, CI, PLUGIN, [Opened Date], State, MIN([Opened Date]) OVER() AS [MIN Opened Date] FROM YourTable WHERE State = 'Open';
方法2:关联子查询
通过交叉连接获取全局最小日期,再关联到Open状态记录:
SELECT t.Number, t.CI, t.PLUGIN, t.[Opened Date], t.State, m.MinOpenedDate AS [MIN Opened Date] FROM YourTable t CROSS JOIN (SELECT MIN([Opened Date]) AS MinOpenedDate FROM YourTable) m WHERE t.State = 'Open';
你之前遇到的问题说明
- 聚合函数不能放WHERE子句:WHERE是在聚合计算前过滤行,聚合函数的结果是基于行集计算的,无法在WHERE中直接使用,需用子查询或窗口函数替代。
- UNION返回所有记录:你的写法可能未正确限定最小日期的子查询,或误用了UNION(会自动去重但可能引入多余行),改用
UNION ALL并精准筛选即可。 - 结合MAX(number)和MIN(opened_at)仅得一条记录:未加GROUP BY时,聚合函数会将全表作为一个分组,仅返回单行结果,不符合多记录需求。
内容的提问来源于stack exchange,提问作者Chrissy Scott
相关产品推荐
相关产品推荐

