Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Combining Case statements

Author  Topic 

sqlbug
Posting Yak Master

201 Posts

Posted - 2009-08-10 : 17:00:53
I am inserting data from one table to another and using case statements in my query like:

SELECT...DATA_VALUE =
(CASE SAMPLE_START_TIME
WHEN '0' THEN CONT_HOUR1_VALUE
WHEN '100'....
....
END),
DATA_FLAG =
((CASE SAMPLE_START_TIME
WHEN '0' THEN CONT_HOUR1_FLAG
WHEN '100'....
....
END)

This is slowing down my query quite a bit, as 24 data and 24 flag columns are there on which the separate case statements are running.
Is there any way I can combine these two together so I can use just one statement?
Thanks.

sqlbug
Posting Yak Master

201 Posts

Posted - 2009-08-11 : 13:27:56
Oh, at least I got some readers.
Go to Top of Page

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2009-08-11 : 13:46:13
I dont' think the CASE statements as you illustrated should slow the query down in any noticeable way. I suspect there is other things about your statement that is. Can you post the whole thing?

Be One with the Optimizer
TG
Go to Top of Page

sqlbug
Posting Yak Master

201 Posts

Posted - 2009-08-11 : 15:18:27
Thanks TG. Here is it:

DECLARE @sdate datetime
SET @sdate = '01-Jul-1988'
WHILE (@sdate <= '31-Dec-1988')
BEGIN
INSERT INTO PLOT_DATA (DATA_SAMPLE_NUM,DATA_PARAMETER,DATA_METHOD,
DATA_UNIT,DATA_DECIMAL,DATA_VALUE,DATA_FLAG)
SELECT [TSAMPLE_NUM],[CONT_PARAMETER],[CONT_METHOD],[CONT_UNITS],
[CONT_DECIMAL],TDATA_VALUE =
(CASE TSAMPLE_START_TIME
WHEN '0' THEN CONT_HOUR1_VALUE
WHEN '100' THEN CONT_HOUR2_VALUE
WHEN '200' THEN CONT_HOUR3_VALUE
WHEN '300' THEN CONT_HOUR4_VALUE
WHEN '400' THEN CONT_HOUR5_VALUE
WHEN '500' THEN CONT_HOUR6_VALUE
WHEN '600' THEN CONT_HOUR7_VALUE
WHEN '700' THEN CONT_HOUR8_VALUE
WHEN '800' THEN CONT_HOUR9_VALUE
WHEN '900' THEN CONT_HOUR10_VALUE
WHEN '1000' THEN CONT_HOUR11_VALUE
WHEN '1100' THEN CONT_HOUR12_VALUE
WHEN '1200' THEN CONT_HOUR13_VALUE
WHEN '1300' THEN CONT_HOUR14_VALUE
WHEN '1400' THEN CONT_HOUR15_VALUE
WHEN '1500' THEN CONT_HOUR16_VALUE
WHEN '1600' THEN CONT_HOUR17_VALUE
WHEN '1700' THEN CONT_HOUR18_VALUE
WHEN '1800' THEN CONT_HOUR19_VALUE
WHEN '1900' THEN CONT_HOUR20_VALUE
WHEN '2000' THEN CONT_HOUR21_VALUE
WHEN '2100' THEN CONT_HOUR22_VALUE
WHEN '2200' THEN CONT_HOUR23_VALUE
WHEN '2300' THEN CONT_HOUR24_VALUE
END),
TDATA_FLAG =
(CASE TSAMPLE_START_TIME
WHEN '0' THEN CONT_HOUR1_FLAG
WHEN '100' THEN CONT_HOUR2_FLAG
WHEN '200' THEN CONT_HOUR3_FLAG
WHEN '300' THEN CONT_HOUR4_FLAG
WHEN '400' THEN CONT_HOUR5_FLAG
WHEN '500' THEN CONT_HOUR6_FLAG
WHEN '600' THEN CONT_HOUR7_FLAG
WHEN '700' THEN CONT_HOUR8_FLAG
WHEN '800' THEN CONT_HOUR9_FLAG
WHEN '900' THEN CONT_HOUR10_FLAG
WHEN '1000' THEN CONT_HOUR11_FLAG
WHEN '1100' THEN CONT_HOUR12_FLAG
WHEN '1200' THEN CONT_HOUR13_FLAG
WHEN '1300' THEN CONT_HOUR14_FLAG
WHEN '1400' THEN CONT_HOUR15_FLAG
WHEN '1500' THEN CONT_HOUR16_FLAG
WHEN '1600' THEN CONT_HOUR17_FLAG
WHEN '1700' THEN CONT_HOUR18_FLAG
WHEN '1800' THEN CONT_HOUR19_FLAG
WHEN '1900' THEN CONT_HOUR20_FLAG
WHEN '2000' THEN CONT_HOUR21_FLAG
WHEN '2100' THEN CONT_HOUR22_FLAG
WHEN '2200' THEN CONT_HOUR23_FLAG
WHEN '2300' THEN CONT_HOUR24_FLAG
END)
FROM PLOT_DATA_TEMP,CONTINUOUS_DATA WHERE TSAMPLE_OLD_NUM = CONT_SAMPLE_NUM
AND TSAMPLE_START_DATE = @sdate ORDER BY TSAMPLE_NUM,CONT_PARAMETER,CONT_METHOD
SET @sdate = @sdate + 1
END
Go to Top of Page

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2009-08-11 : 15:39:27
Funny that you thought the slow performance was the CASE statements when you have a loop in there for 183 seperate selects from the same table :) try this non-looping method to see if there is an improvement:

DECLARE @sdate_start datetime
,@sdate_end datetime
select @sdate_start = '01-Jul-1988'
,@sdate_end = '31-Dec-1988'

declare @dates table (sdate datetime)

insert @dates (sdate)
select dateadd(day, number, @sdate_start)
from master..spt_values
where type = 'P'
and number < datediff(day, @sdate_start, @sdate_end)

INSERT INTO PLOT_DATA
(DATA_SAMPLE_NUM
,DATA_PARAMETER
,DATA_METHOD
,DATA_UNIT
,DATA_DECIMAL
,DATA_VALUE
,DATA_FLAG)

SELECT [TSAMPLE_NUM]
,[CONT_PARAMETER]
,[CONT_METHOD]
,[CONT_UNITS]
,[CONT_DECIMAL]
,TDATA_VALUE =
CASE TSAMPLE_START_TIME
WHEN '0' THEN CONT_HOUR1_VALUE
WHEN '100' THEN CONT_HOUR2_VALUE
WHEN '200' THEN CONT_HOUR3_VALUE
WHEN '300' THEN CONT_HOUR4_VALUE
WHEN '400' THEN CONT_HOUR5_VALUE
WHEN '500' THEN CONT_HOUR6_VALUE
WHEN '600' THEN CONT_HOUR7_VALUE
WHEN '700' THEN CONT_HOUR8_VALUE
WHEN '800' THEN CONT_HOUR9_VALUE
WHEN '900' THEN CONT_HOUR10_VALUE
WHEN '1000' THEN CONT_HOUR11_VALUE
WHEN '1100' THEN CONT_HOUR12_VALUE
WHEN '1200' THEN CONT_HOUR13_VALUE
WHEN '1300' THEN CONT_HOUR14_VALUE
WHEN '1400' THEN CONT_HOUR15_VALUE
WHEN '1500' THEN CONT_HOUR16_VALUE
WHEN '1600' THEN CONT_HOUR17_VALUE
WHEN '1700' THEN CONT_HOUR18_VALUE
WHEN '1800' THEN CONT_HOUR19_VALUE
WHEN '1900' THEN CONT_HOUR20_VALUE
WHEN '2000' THEN CONT_HOUR21_VALUE
WHEN '2100' THEN CONT_HOUR22_VALUE
WHEN '2200' THEN CONT_HOUR23_VALUE
WHEN '2300' THEN CONT_HOUR24_VALUE
END
,TDATA_FLAG =
CASE TSAMPLE_START_TIME
WHEN '0' THEN CONT_HOUR1_FLAG
WHEN '100' THEN CONT_HOUR2_FLAG
WHEN '200' THEN CONT_HOUR3_FLAG
WHEN '300' THEN CONT_HOUR4_FLAG
WHEN '400' THEN CONT_HOUR5_FLAG
WHEN '500' THEN CONT_HOUR6_FLAG
WHEN '600' THEN CONT_HOUR7_FLAG
WHEN '700' THEN CONT_HOUR8_FLAG
WHEN '800' THEN CONT_HOUR9_FLAG
WHEN '900' THEN CONT_HOUR10_FLAG
WHEN '1000' THEN CONT_HOUR11_FLAG
WHEN '1100' THEN CONT_HOUR12_FLAG
WHEN '1200' THEN CONT_HOUR13_FLAG
WHEN '1300' THEN CONT_HOUR14_FLAG
WHEN '1400' THEN CONT_HOUR15_FLAG
WHEN '1500' THEN CONT_HOUR16_FLAG
WHEN '1600' THEN CONT_HOUR17_FLAG
WHEN '1700' THEN CONT_HOUR18_FLAG
WHEN '1800' THEN CONT_HOUR19_FLAG
WHEN '1900' THEN CONT_HOUR20_FLAG
WHEN '2000' THEN CONT_HOUR21_FLAG
WHEN '2100' THEN CONT_HOUR22_FLAG
WHEN '2200' THEN CONT_HOUR23_FLAG
WHEN '2300' THEN CONT_HOUR24_FLAG
END

FROM PLOT_DATA_TEMP
inner join CONTINUOUS_DATA
on TSAMPLE_OLD_NUM = CONT_SAMPLE_NUM
inner join @dates d
on d.sdate = TSAMPLE_START_DATE

ORDER BY TSAMPLE_NUM
,CONT_PARAMETER,CONT_METHOD


Be One with the Optimizer
TG
Go to Top of Page

sqlbug
Posting Yak Master

201 Posts

Posted - 2009-08-11 : 16:06:14
I didn't think that I can get rid of the loop. So was looking at the other things. I'll test it and let you know.

Thanks so much.
Go to Top of Page

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2009-08-11 : 16:25:21
You're welcome. If TSAMPLE_START_DATE only has one row per day as opposed to several rows with different times. then you could remove the @dates table variable and just add a WHERE clause:

where TSAMPLE_START_DATE between @sdate_start and @sdate_end

Be One with the Optimizer
TG
Go to Top of Page

sqlbug
Posting Yak Master

201 Posts

Posted - 2009-08-11 : 16:31:16
Hi TG, Its 184 days, not 183 days right?

So, should it be like:
and number <= datediff(day, @sdate_start, @sdate_end)
or
and number < datediff(day, @sdate_start, @sdate_end + 1)

And yes, it was pretty fast - just 47 seconds.
Thanks again.
Go to Top of Page

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2009-08-11 : 16:35:57
Yes, you're right. Good catch.
How long was it taking previously?

Be One with the Optimizer
TG
Go to Top of Page

sqlbug
Posting Yak Master

201 Posts

Posted - 2009-08-11 : 17:31:39
Over an hour most of the times!
Go to Top of Page
   

- Advertisement -