tags:

views:

71

answers:

3

I apologize for the vague title. I am attempting to write a query that returns an alias column with matching values (resulting from an IN) as well as an alias column with values that do not match (using NOT IN). I want the result set to have: userId | matches | nonmatches. I currently have the following query which returns the matches as expected. I am having trouble getting the nonmatches in the result set -- that is, from a NOT IN statement

SET @userId = 9;
SELECT ug.user_id, COUNT(DISTINCT goal_id) as matches
FROM user_goal ug
WHERE ug.user_id!=@userId
AND goal_id IN (SELECT iug.goal_id FROM user_goal iug WHERE user_id=@userId)
GROUP BY user_id ORDER BY matches DESC LIMIT 4

So, the NOT IN would look something like this:

goal_id NOT IN(SELECT uggg.goal_id FROM user_goal uggg WHERE user_id=@userId) AS nonmatches

I am just not sure how to incorporate the NOT IN statement in my query so I get all the results

A: 

group it by one another param, fix one param that will be used if there are goals from sub query

TriLLi
I'm not sure I understand what you mean by "fix one param", can you kindly explain?
UltraVi01
just check if returned goal belongs to user then set some value to "1" else set it to "0" and seted value can have alias "x"so you can group them by user_id, x
TriLLi
A: 

I think a UNION is what you need:

SET @userId = 9;

SELECT ug.user_id, COUNT(DISTINCT goal_id) as matches
FROM user_goal ug
WHERE ug.user_id!=@userId
AND goal_id IN (SELECT iug.goal_id FROM user_goal iug WHERE user_id=@userId)
GROUP BY user_id ORDER BY matches DESC LIMIT 4

union all

SELECT ug.user_id, COUNT(DISTINCT goal_id) as matches
FROM user_goal ug
WHERE ug.user_id!=@userId
AND goal_id NOT IN(SELECT uggg.goal_id FROM user_goal uggg WHERE user_id=@userId)
GROUP BY user_id ORDER BY matches DESC LIMIT 4
Ray
Thanks, is there something I need to change with the GROUP BY?
UltraVi01
I wouldn't think so, if your select list is the same for both parts of the query. I am not a mysql guy, so I don't know if there are other requirements that I missed, but it looks like pretty standard stuff to me.
Ray
A: 

Try this (could be simplified and further optimized if mysql have CTE though):

select u.user_id, the_matches.matches, the_nonmatches.nonmatches
from user u 
left join 
(    
    SELECT ug.user_id, COUNT(DISTINCT goal_id) as matches
    FROM user_goal ug
    WHERE ug.user_id!=@userId
    AND goal_id IN (SELECT iug.goal_id FROM user_goal iug WHERE user_id=@userId)
    GROUP BY user_id 
    ORDER BY matches DESC LIMIT 4
) as the_matches on the_matches.user_id = u.user_id
left join
(
    SELECT ug.user_id, COUNT(DISTINCT goal_id) as nonmatches
    FROM user_goal ug
    WHERE ug.user_id!=@userId
    AND goal_id NOT IN(SELECT uggg.goal_id FROM user_goal uggg WHERE user_id=@userId) 
    GROUP BY user_id 
) as the_nonmatches on the_nonmatches.user_id = u.user_id
Michael Buen