Reputation: 1912
I have this sample data
+------+------------+------------+
| 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'})
I'm expected to get this data
+------+------------+------------+
| CODE | START_DATE | END_DATE |
+------+------------+------------+
| 0001 | 2012-01-01 | NULL |
+------+------------+------------+
| 0002 | 2012-02-01 | NULL |
+------+------------+------------+
| 0003 | 2012-02-01 | 2012-03-31 |
+------+------------+------------+
currently in SQL Server 2005, I use this query
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
I'm cheating NULL value to date 9999-12-31
I'm looking for better solution for this
thank you
Upvotes: 3
Views: 1569
Reputation: 5803
You could utilize the fact that the COUNT
of NULL
and NOT NULL
columns will be different. So the script can go like this:
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
Upvotes: 1
Reputation: 1624
This script uses a cte (common table expressions) to first get null end_dates and does a left join on it. It eliminates the need for the hard-coded arbitrary date you are using.
As it requires an extra query it would be slower than your initial solution.
So it also depends on the number of records and how frequent this script would be invoked, in deciding the best solution.
;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
Upvotes: 0