将 NULL 视为 MAX 日期

Treat NULL as MAX Date

我需要检索每个客户的 MAX ResponsibleEndDate。如果有 NULL,则将其视为 MAX 日期。

CREATE TABLE example
(Id INT, ClientId INT, ClientName VARCHAR(100), ResponsibleId INT, ResponsibleName VARCHAR(100), ResponsibleStartDate DATE, ResponsibleEndDate DATE);

INSERT INTO example
VALUES
(1, 123, 'John Smith', NULL, NULL, NULL, NULL),
(2, 234, 'Thomas Anderson', 12345, 'Tom Cruise', '2019-04-13', '2020-09-15'),
(3, 234, 'Thomas Anderson', 23456, 'John Travolta', '2020-09-16', '2022-01-15'),
(4, 234, 'Thomas Anderson', 37890, 'Van Damm', '2022-01-16', NULL),
(5, 345, 'Mary Tron', NULL, NULL, NULL, NULL),
(6, 456, 'Jackie Chan', 56789, 'Leo Messi', '2018-05-18', '2022-01-18'),
(7, 567, 'Cristiano Ronaldo', 12345, 'Tom Cruise', '2019-05-28', '2021-08-20'),
(8, 567, 'Cristiano Ronaldo', 37890, 'Van Damm', '2021-07-15', '2022-01-15'),
(9, 567, 'Cristiano Ronaldo', 17956, 'Harry Potter', '2022-01-25', NULL)

我需要的输出:

Id ClientId ClientName ResponsibleId ResponsibleName ResponsibleStartDate ResponsibleEndDate MaxDate
1 123 John Smith NULL NULL NULL NULL NULL
2 234 Thomas Anderson 12345 Tom Cruise 2019-04-13 2020-09-15 NULL
3 234 Thomas Anderson 23456 John Travolta 2020-09-16 2022-01-15 NULL
4 234 Thomas Anderson 37890 Van Damm 2022-01-16 NULL NULL
5 345 Mary Tron NULL NULL NULL NULL NULL
6 456 Jackie Chan 56789 Leo Messi 2018-05-18 2022-01-18 2022-01-18
7 567 Cristiano Ronaldo 12345 Tom Cruise 2019-05-28 2021-08-20 NULL
8 567 Cristiano Ronaldo 37890 Van Damm 2021-07-15 2022-01-15 NULL
9 567 Cristiano Ronaldo 17956 Harry Potter 2022-01-25 NULL NULL

我的查询:

SELECT *,
    MAX(ResponsibleEndDate)OVER(PARTITION BY ClientId) AS MAX_END_DATE    
FROM example
ORDER BY ClientId, ResponsibleStartDate

聚合函数,在 T-SQL 中,忽略 NULL 值并且 NULL 也被视为具有 最低 值,而不是最高值.

因此,您需要使用几个函数将 NULL 替换为任意高的值,然后再次 NULL

SELECT ClientID,
       ClientName,
       {Rest of your columns},
       NULLIF(MAX(ISNULL(ResponsibleEndDate,'99991231')) OVER (PARTITION BY ClientId),'99991231') AS MAX_END_DATE    
FROM dbo.example
ORDER BY ClientId,
         ResponsibleStartDate;

另一种选择是显式检查 NULL

是否存在
SELECT
  ClientID,
  ClientName,
       {Rest of your columns},
  CASE WHEN COUNT(CASE WHEN ResponsibleEndDate IS NULL THEN 1 END) OVER (PARTITION BY ClientId) = 0
      THEN MAX(ResponsibleEndDate) OVER (PARTITION BY ClientId)
  END AS MAX_END_DATE    
FROM dbo.example
ORDER BY
  ClientId,
  ResponsibleStartDate;

一个细微的变化是 CASE WHEN COUNT(ResponsibleEndDate) = COUNT(*) 因为 COUNT 只会计算 non-null 个值