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
 aternative to CASE?

Author  Topic 

Larno
Starting Member

2 Posts

Posted - 2010-05-10 : 23:36:06
Hi all,

This is probably pretty simple but I am quite new to SQL. I can get the results i want but the query would contain a truely massive CASE block so I am hoping you guys know a much simpler way to achieve my goals.

What i have is a customer loyalty program and i am trying to add up all of the customers total spends and then split the customers up in blocks of $20. ie if 50 people have spent only $35 and 10 people have spent $65 then i would want the below results.

Example:
0 - 20 = 0 people
20 - 40 = 50 people
40 - 60 = 0 people
60 - 80 = 10 people
etc..

I can do this with CASE like:

SELECT CASE
WHEN SUM(added_value) IS NULL
THEN 'No Balance'
WHEN SUM(added_value) <= 20
THEN '$0 - $20'
WHEN SUM(added_value) BETWEEN 20 AND 40
THEN '$20 - $40'
WHEN SUM(added_value) BETWEEN 40 AND 60
THEN '$40 - $60'
WHEN SUM(added_value) BETWEEN 60 AND 80
THEN '$60 - $80'
ELSE 'Higher Than $80'
END AS [SPEND]
,COUNT(DISTINCT customer_code) AS [CUSTOMER COUNT]
FROM dbo.CLUB_SALES

but my issue is that i need to split the cust counts in $20 brackets from $0 all the way to $5000 dollars which is alot if WHEN/ THENS :(

is their an easier way ?

many thanks
Lance House


jezemine
Master Smack Fu Yak Hacker

2886 Posts

Posted - 2010-05-10 : 23:55:20
change the case to this:

convert(varchar,20*(sum(added_value)/20)) + ' to ' + convert(varchar,(20*(sum(added_value)/20)+19)) as SPEND



elsasoft.org
Go to Top of Page

malpashaa
Constraint Violating Yak Guru

264 Posts

Posted - 2010-05-11 : 00:04:51
You can use (real, temp or variable) table for this like:

DECLARE @AddedValuesSlices TABLE
(
end_value INT NOT NULL PRIMARY KEY,
slice_name VARCHAR(100) NOT NULL
);

INSERT INTO @AddedValuesSlices(end_value, slice_name)
SELECT 0, 'No Balance' UNION ALL
SELECT 20, '$0 - $20' UNION ALL
SELECT 40, '$20 - $40' UNION ALL
SELECT 60, '$40 - $60' UNION ALL
SELECT 80, '$60 - $80' UNION ALL
SELECT 2147483647, 'Higher Than $80';

SELECT S.[SPEND], T.[CUSTOMER COUNT]
FROM (SELECT ISNULL(SUM(added_value), 0) AS [SPEND], COUNT(DISTINCT customer_code) AS [CUSTOMER COUNT]
FROM dbo.CLUB_SALES) AS T
CROSS APPLY
(SELECT TOP(1) S.slice_name AS [SPEND]
FROM @AddedValuesSlices AS S
WHERE S.end_value >= T.SPEND
ORDER BY S.end_value ASC) AS S
Go to Top of Page

Larno
Starting Member

2 Posts

Posted - 2010-05-11 : 00:16:09
Hi thanks for the replys,

jezemine: i tried your query (hopefully how you intended) but it only gave me 1 result. Not sure if this is because the added_value column we are summing is data type 'money' or not and its not and somethign odd is happeneing.

SELECT convert(varchar,20*(sum(added_value)/20)) + ' to ' + convert(varchar,(20*(sum(added_value)/20)+19)) as SPEND, COUNT(DISTINCT customer_code) AS [CUSTOMER COUNT]
FROM dbo.CLUB_SALES

Results:
SPEND
92314330.81 to 92314349.81

CUSTOMER COUNT
446654

malpashaa: with your option wouldn't i still need to type out all of the $20 brackets maually into the insert into section?

Thanks
Lance
Go to Top of Page

jezemine
Master Smack Fu Yak Hacker

2886 Posts

Posted - 2010-05-11 : 00:31:46
well, since you are doing a SUM, if you want more than one row returned you need to add a column to group by and a group by clause.

Since I don't know what your table looks like I have no idea what you want to group by. Also you'll have to convert the sum to an int for the integer division trick I was using to work.

Look at this for an example of what I was thinking:


select
number,
convert(varchar,20*(number/20)) + ' to ' + convert(varchar,(20*(number/20)+19))
from master.dbo.spt_values s where s.type='P'



elsasoft.org
Go to Top of Page
   

- Advertisement -