2012-11-30 172 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