我有一些看起来像这样的数据:
数字 | CI | 插件 | 开放日期 | 状态 |
---|---|---|---|---|
1 | XYZ | A123 | 1/1/2023 | 关闭 |
2 | XYZ | A123 | 2/1/2023 | 关闭 |
3 | XYZ | A123 | 3/1/2023 | 关闭 |
4 | XYZ | A123 | 4/1/2023 | 打开 |
5 | XYZ | A123 | 5/1/2023 | 打开 |
我想要查询的结果要么给我:
数字 | CI | 插件 | 开放日期 | 状态 |
---|---|---|---|---|
1 | XYZ | A123 | 1/1/2023 | 关闭 |
4 | XYZ | A123 | 4/1/2023 | 打开 |
5 | XYZ | A123 | 5/1/2023 | 打开 |
数字 | CI | 插件 | 开放日期 | 状态 | 最低开放日期 |
---|---|---|---|---|---|
4 | XYZ | A123 | 4/1/2023 | 打开 | 1/1/2023 |
5 | XYZ | A123 | 5/1/2023 | 打开 | 1/1/2023 |
我试图过滤 State = Open OR min(opened_at) = opened_at 但我得到的错误是聚合不能用于 where 子句。
我尝试在 MIN(opened_at) 的查询中使用 MAX(number),但后来我只得到 Number = 5 的记录。我还需要记录 Number = 4.
我还尝试创建两个查询,一个只有打开的记录,一个有 MIN(打开日期)并将它们合并,但这只给了我所有的记录。
使用 SSMS 19。 SQL 服务器(视窗 SQL 服务器) 任何指导表示赞赏。
我们使用窗口函数
min()over()
找到第一个日期,然后 where
只显示 state = 'open'
。注意它必须是嵌套的,否则它会过滤掉min(Opened_Date)
.
select *
from
(
select *
,min(Opened_Date) over(order by Opened_Date) as MIN_Opened_Date
from t
) t
where State = 'Open'
数字 | CI | 插件 | 开业日期 | 状态 | MIN_Opened_Date |
---|---|---|---|---|---|
4 | XYZ | A123 | 2023-04-01 | 打开 | 2023-01-01 |
5 | XYZ | A123 | 2023-05-01 | 打开 | 2023-01-01 |
听起来您只是没有将其包装在子查询中,因此窗口函数可用于 where 子句:
DECLARE @Table TABLE (Number INT, CI NVARCHAR(3), PLUGIN NVARCHAR(4), OpenedDate DATE, State NVARCHAR(6));
INSERT INTO @Table (Number, CI, PLUGIN, OpenedDate, State) VALUES
(1, 'XYZ', 'A123', '1/1/2023', 'Closed'),
(2, 'XYZ', 'A123', '2/1/2023', 'Closed'),
(3, 'XYZ', 'A123', '3/1/2023', 'Closed'),
(4, 'XYZ', 'A123', '4/1/2023', 'Open'),
(5, 'XYZ', 'A123', '5/1/2023', 'Open');
SELECT a.Number, a.CI, a.PLUGIN, a.OpenedDate, a.State, a.MinOpenDate
FROM (
SELECT a.Number, a.CI, a.PLUGIN, a.OpenedDate, a.State, MIN(a.OpenedDate) OVER (PARTITION BY a.CI, a.Plugin ORDER BY a.OpenedDate) AS MinOpenDate
FROM @Table a
) a
WHERE a.OpenedDate = a.MinOpenDate
OR a.State = 'Open'
我们完全按照您的描述进行操作,但我们现在可以在 where 子句中引用窗口聚合列。
作为旁注,提供易于重现的 DDL/DML 使人们更容易回答您的问题。