Reputation: 339
I have a pretty flat table - tbl_values which has userids as well as netAmounts in a given row. In the example below, 2280 has no records in the past 30 days based on the timestamp.
I'd expect this to return 3 rows, with 2280 as "0" - but I'm only getting 2 back? Am I missing something obvious here?
SELECT userid, (COALESCE(SUM(netAmount),0)) as Sum FROM `tbl_values` where userid in (2280, 399, 2282) and date > (select DATE_SUB(NOW(), INTERVAL 30 day)) GROUP BY userid
Upvotes: 0
Views: 77
Reputation: 62861
Assuming you always want to return the user, regardless of rather they have a matching record in tbl_values
, what you're looking for is an outer join
:
SELECT u.userid, COALESCE(SUM(v.netAmount),0) as Sum
FROM (
SELECT 2280 userid UNION ALL
SELECT 399 UNION ALL
SELECT 2282
) u
LEFT JOIN `tbl_values` v ON u.userid = v.userid AND
v.date > DATE_SUB(NOW(), INTERVAL 30 day)
GROUP BY u.userid
If you perhaps have a Users
table, then you can use it instead of the subquery.
SELECT u.userid, COALESCE(SUM(v.netAmount),0) as Sum
FROM users u
LEFT JOIN `tbl_values` v ON u.userid = v.userid AND
v.date > DATE_SUB(NOW(), INTERVAL 30 day)
WHERE u.userid in (2280, 399, 2282)
GROUP BY u.userid
Upvotes: 1
Reputation: 1271151
This is your query:
SELECT userid, (COALESCE(SUM(netAmount),0)) as Sum
FROM `tbl_values`
where userid in (2280, 399, 2282) and
date > (select DATE_SUB(NOW(), INTERVAL 30 day))
GROUP BY userid;
The filter in the where
clause finds no rows that match for user id 2280. Assuming that at least one row exists somewhere, you can get what you want by moving the date
comparison to a conditional aggregation:
SELECT userid,
sum(case when date > DATE_SUB(NOW(), INTERVAL 30 day)
then netAmount else 0
end) as Sum
FROM `tbl_values`
WHERE userid in (2280, 399, 2282)
GROUP BY userid;
EDIT:
If you really want all three results, then use a left join
:
SELECT u.userid,
coalesce(sum(netAmount), 0) as Sum
FROM (select 2280 as userid union all
select 399 union all
select 2282
) u left join
tbl_values t
on u.userid = t.userid and
t.date > DATE_SUB(NOW(), INTERVAL 30 day)
GROUP BY u.userid;
Upvotes: 0