0

This is the query:

SELECT a.id, a.userName,if(o.userId=1,'C',if(i.userId=1,'I','N')) AS relation 
       FROM tbl_users AS a 
       LEFT JOIN tbl_contacts AS o ON a.id = o.contactId 
       LEFT JOIN tbl_invites AS i ON a.id = i.invitedId 
  ORDER BY relation

This returns the output as follows:

+----+--------------+-------------+
| ID | USERNAME     | RELATION    | 
+----+--------------+-------------+
|  1 |          ray |           C | 
+----+--------------+-------------+
|  2 |         john |           I | 
+----+--------------+-------------+
|  1 |         ray  |           N | 
+----+--------------+-------------+

I need to remove the third row from the select query by checking if possible that id is duplicate. The priority is as follows:

C -> I -> N. So since there is already a "ray" with a C, I dont want it again with an I or N.

I tried adding distinct(a.id) but it doesn't work. How do I do this?

Why doesn't DISTINCT work for this?

Martin
  • 22,212
  • 11
  • 70
  • 132
Saeesh Tendulkar
  • 638
  • 12
  • 30

2 Answers2

1

From the specs you gave, all you have to do is group by ID and username, then pick the lowest value of relation you can find (since C < I < N)

SELECT a.id, a.userName, MIN(if(o.userId=1,'C',if(i.userId=1,'I','N'))) AS relation 
    FROM tbl_users AS a 
    LEFT JOIN tbl_contacts AS o ON a.id = o.contactId 
    LEFT JOIN tbl_invites AS i ON a.id = i.invitedId 
GROUP BY a.id, a.username
Leo Aso
  • 11,898
  • 3
  • 25
  • 46
1

There are multiple ways to get the group-wise maximum/minimum as you can see in this manual page.

The best one suited for you is the first one, if the order of the rows can not be defined by alphabetic order.

In this case, given if the desired order were z-a-m (see Rams' comment) you'd need the FIELD() function.

So your answer is

SELECT 
a.id, 
a.userName,
if(o.userId=1,'C',if(i.userId=1,'I','N')) AS relation 
FROM tbl_users a
LEFT JOIN tbl_contacts AS o ON a.id = o.contactId 
LEFT JOIN tbl_invites AS i ON a.id = i.invitedId 
WHERE 
if(o.userId=1,'C',if(i.userId=1,'I','N')) = (
    SELECT 
    if(o.userId=1,'C',if(i.userId=1,'I','N')) AS relation 
    FROM tbl_users aa
    LEFT JOIN tbl_contacts AS o ON aa.id = o.contactId 
    LEFT JOIN tbl_invites AS i ON aa.id = i.invitedId 
    WHERE aa.id = a.id AND aa.userName = a.userName
    ORDER BY FIELD(relation, 'N', 'I', 'C') DESC 
    LIMIT 1
)

Note, you can also do it like ORDER BY FIELD(relation, 'C', 'I', 'N') to have it more readable / intuitive. I turned it the other way round, because if you'd have the possibility of having a 'X' in the relation, the FIELD() function would have returned 0 because X is not specified as a parameter. Therefore it would be sorted before 'C'. By sorting descending and turning the order of the parameters around this can not happen.

fancyPants
  • 50,732
  • 33
  • 89
  • 96