Reputation: 2533
I am having difficulty with a SQL query. I'm using sqlite.
I have a table expenses
. I'm trying to use a CASE
statement to select and sum values. Here's some sample data:
This is the query which is not getting what I'd like...
SELECT e.category,
CASE
WHEN e.schedule ='None' AND e.created_at > '2014-02-01 00:00:00 +0000' THEN SUM(e.amount)
WHEN e.schedule = 'Daily' THEN SUM(e.amount)*28.000000
WHEN e.schedule = 'Mon - Fri' THEN SUM(e.amount)*20
WHEN e.schedule = 'Weekly' THEN SUM(e.amount)*4.000000
WHEN e.schedule = 'Every 4 Weeks' THEN SUM(e.amount)*1.083333333333
WHEN e.schedule = 'Monthly' THEN SUM(e.amount)*1
ELSE 0
END
AS totalValue FROM expenses e GROUP BY e.category ORDER BY e.category
Below is a pic of what the query returns.
What I would like to see in total value for Housing
420, this is because there is are three records with the category
"Housing", one of which has a schedule
of "None" (record id 2) and was created in January. The other two (records 10 and 16) have a schedule
of Monthly. In my CASE
I try to only select the schedules with a created_at
greater than the 1st of Feb:
WHEN e.schedule ='None' AND e.created_at > '2014-02-01 00:00:00 +0000' THEN SUM(e.amount)
Or with a schedule value other than "None", in this case:
WHEN e.schedule = 'Monthly' THEN SUM(e.amount)
Unfortunately I'm getting a result of 495 (300 + 120 + 75). It's summing all the records with a particular category
if it finds a record that fits the case statement!
Please can you help me rewrite the case so that I get the results I'm looking for.
Upvotes: 2
Views: 6283
Reputation: 1270191
One problem with the query is that you are using e.schedule
in the select
list but it is not in a group by
. This is usually the sign of a problem.
I think you want to move the entire case
statement inside the sum()
:
SELECT e.category,
SUM(CASE WHEN e.schedule ='None' AND e.created_at > '2014-02-01 00:00:00 +0000' THEN e.amount
WHEN e.schedule = 'Daily' THEN e.amount*28.000000
WHEN e.schedule = 'Mon - Fri' THEN e.amount*20
WHEN e.schedule = 'Weekly' THEN e.amount*4.000000
WHEN e.schedule = 'Every 4 Weeks' THEN e.amount*1.083333333333
WHEN e.schedule = 'Monthly' THEN e.amount*1
ELSE 0
END) as totalValue
FROM expenses e
GROUP BY e.category
ORDER BY e.category;
Otherwise, you might want to move e.schedule
to the group by
clause to have a separate row for each schedule within each category.
Upvotes: 8