2012-11-30 173 views
3

我有这个样本数据聚合函数返回null

+------+------------+------------+ 
| 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 

我欺骗NULL值迄今为止9999-12-31

我在寻找更好的解决这个

谢谢

+1

我认为你在做什么是好的。 –

回答

1

你可以利用这样一个事实:NULLNOT NULLCOUNT会有所不同。所以脚本可以这样:

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 
0

这个脚本使用的CTE(共同表表达式)首先得到null 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