>我有这个样本数据
+------+------------+------------+
| CODE | START_DATE | END_DATE |
+------+------------+------------+
| 0001 | 2012-01-01 | 2012-01-31 |
+------+------------+------------+
| 0001 | 2012-02-01 | 2012-02-29 |
+------+------------+------------+
| 0001 | 2012-03-01 | NULL |
+------+------------+------------+
| 0002 | 2012-02-01 | 2012-02-29 |
+------+------------+------------+
| 0002 | 2012-03-01 | 2012-03-31 |
+------+------------+------------+
| 0002 | 2012-04-01 | NULL |
+------+------------+------------+
| 0003 | 2012-02-01 | 2012-02-29 |
+------+------------+------------+
| 0003 | 2012-03-01 | 2012-03-31 |
+------+------------+------------+
DDL
CREATE TABLE SAMPLE
(
CODE VARCHAR(4),
START_DATE DATETIME,
END_DATE DATETIME
)
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0001', {d '2012-01-01'}, {d '2012-01-31'})
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0001', {d '2012-02-01'}, {d '2012-02-29'})
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0001', {d '2012-03-01'}, NULL)
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0002', {d '2012-02-01'}, {d '2012-02-29'})
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0002', {d '2012-03-01'}, {d '2012-03-31'})
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0002', {d '2012-04-01'}, NULL)
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0003', {d '2012-02-01'}, {d '2012-02-29'})
INSERT INTO SAMPLE (CODE, START_DATE, END_DATE) VALUES ('0003', {d '2012-03-01'}, {d '2012-03-31'})
我应该得到这些数据
+------+------------+------------+
| CODE | START_DATE | END_DATE |
+------+------------+------------+
| 0001 | 2012-01-01 | NULL |
+------+------------+------------+
| 0002 | 2012-02-01 | NULL |
+------+------------+------------+
| 0003 | 2012-02-01 | 2012-03-31 |
+------+------------+------------+
目前在 SQL Server 2005 中,我使用此查询
SELECT CODE,
MIN(START_DATE) AS START_DATE,
CASE
WHEN MAX(ISNULL(END_DATE, {d '9999-12-31'})) = {d '9999-12-31'}
THEN NULL
ELSE
MAX(END_DATE)
END AS END_DATE
FROM SAMPLE
GROUP BY CODE
我正在作弊 空值 到目前为止 9999-12-31
我正在寻找更好的解决方案
谢谢
您可以利用NULL
列和NOT NULL
列的COUNT
不同的事实。所以脚本可以像这样:
SELECT CODE,
MIN(START_DATE) AS START_DATE,
CASE
WHEN COUNT(*) > COUNT(END_DATE)
THEN NULL
ELSE
MAX(END_DATE)
END AS END_DATE
FROM SAMPLE
GROUP BY CODE
此脚本使用 cte(公用表表达式)首先获取空end_dates并对其执行左连接。它消除了对您使用的硬编码任意日期的需要。
由于它需要额外的查询,因此它将比初始解决方案慢。
因此,在决定最佳解决方案时,它还取决于记录的数量以及调用此脚本的频率。
;WITH NULL_END_DATES_CTE AS (SELECT CODE FROM SAMPLE WHERE END_DATE IS NULL)
SELECT S.CODE,
MIN(S.START_DATE) AS START_DATE,
CASE WHEN C.CODE IS NULL THEN MAX(S.END_DATE) ELSE NULL END AS END_DATE
FROM SAMPLE S
LEFT JOIN NULL_END_DATES_CTE C ON C.CODE = S.CODE
GROUP BY S.CODE,C.CODE
ORDER BY S.CODE