Reputation: 289
I have this table...
--------------------------------------
| user_id | status | status_date |
--------------------------------------
| 1 | Current | 2012-08-01 |
| 1 | Referral | 2012-03-14 |
| 2 | Referral | 2012-04-23 |
| | | |
--------------------------------------
How would I query to find a distinct user_id who has a referral date before 2012-06-30 AND either a current date of after 2012-06-30 or no current status record at all?
Database is MySQL.
Upvotes: 2
Views: 123
Reputation: 41428
Avoid doing innner selects with MySQL. All versions up to and including 5.5 cannot optimize properly with them. Use JOINs:
SELECT distinct t1.user_id
FROM tablename t1
LEFT JOIN tablename t2 on t1.user_id = t2.user_id AND t1.status != t2.status
WHERE t1.status = 'Referral'
AND t1.status_date '2012-06-30'
AND ( (t2.status IS NULL) OR
(t2.status = 'Current' AND t2.status_date > '2012-06-30'));
Upvotes: 0
Reputation: 69769
You can do this using a LEFT JOIN:
SELECT DISTINCT T.User_ID
FROM T
LEFT JOIN T T2
ON t.User_ID = T2.User_ID
AND t2.Status = 'Current'
WHERE T.Status_Date < '20120630'
AND T.Status = 'Referral'
AND (t2.Status_Date > '20120630' OR t2.Status_date IS NULL)
Or, using GROUP BY
with HAVING
and COUNT(CASE ...)
SELECT t.User_ID
FROM T
GROUP BY t.user_ID
HAVING COUNT(CASE WHEN t.Status = 'Referral' AND t.Status_Date < '20120630' THEN 1 END) > 0
AND ( COUNT(CASE WHEN t.Status = 'Current' AND t.Status_Date > '20120630' THEN 1 END) > 0
OR COUNT(CASE WHEN t.Status = 'Current' THEN 1 ELSE 0 END) = 0
)
It will depend on your indexes and amount of data as to which performs better, I'd imagine in most cases it will be the former
Upvotes: 2
Reputation: 70638
This should do it:
SELECT DISTINCT user_id
FROM YourTable T
WHERE status = 'Referral'
AND status_date < '2012-06-30'
AND NOT EXISTS (SELECT user_id FROM YourTable
WHERE user_id = T.user_id AND status = 'Current'
AND status_date < '2012-06-30')
Upvotes: 1