简体   繁体   中英

SQL: Get null as a return value for rows that don't match query

I have a table, Entity and a table Friends . I want to get the names of people who have visited the same location, but I only want to return them if they are not friends with the person (suggested friend query). In order to do this I have written the following query:

SELECT Entity_Id,
       Category AS FC
 FROM  entity
 LEFT 
 JOIN  friends 
   ON  entity.Entity_Id = friends.Entity_Id1 
   OR  entity.Entity_Id = friends.Entity_Id2
WHERE  Entity_Id IN ( :list_of_ids ) 
  AND  Entity_Id != :user_id
  AND  Category != 4
GROUP 
   BY  Entity_Id

:list_of_ids is a comma separated list of user id's and in my test query there are 82 users, however only 15 users are returned from the query, where the users returned are users who have a relationship with :user_id.

Any user who does not have a relationship in the table is not returned in the query. I thought by providing a LEFT OUTER JOIN it would return NULL for fields that were not found in the friends table.

----- EXPECTED -----
--------------------
Entity_Id         FC
--------------------
1                  3
2                  2
3                  2
4               null
52              null
64              null

------ ACTUAL -------
---------------------
Entity_Id          FC
---------------------
1                  3
2                  2
3                  2

The structure of my friends table is as follows, also note that it supports reciprocal relationships if that is any help...

------ FRIENDS ------
---------------------
fid                PK
entity_id1        INT
entity_id2        INT
category          INT  -- 1 = Facebook, 2 = G+, 3 = App, 4 = Blocked

How can I return the users who have a missing relationship?

You want a left outer join . But, with a left join , the conditions on the second table need to go into the on clause:

SELECT e.Entity_Id, f.Category AS FC
FROM entity e LEFT JOIN
     friends f
     ON e.Entity_Id IN (f.Entity_Id1, f.Entity_Id2) AND
        f.category <> 4
WHERE e.Entity_Id IN ( :list_of_ids ) AND
      e.Entity_Id <> :user_id
GROUP BY e.Entity_Id;

When you have the condition on category in the WHERE clause, you turn the LEFT JOIN into an INNER JOIN . When there is no match, category has a value of NULL , which fails the comparison.

Which table does the Category belong to? If its a friends column, move Category != 4 from WHERE to ON to get true outer join. (Otherwise it executes as a regular innner join...):

SELECT Entity_Id, Category AS FC
FROM  entity
 LEFT JOIN  friends 
   ON  (entity.Entity_Id = friends.Entity_Id1 
        OR entity.Entity_Id = friends.Entity_Id2)
   AND Category != 4
WHERE  entity.Entity_Id IN ( :list_of_ids ) 
  AND  entity.Entity_Id != :user_id
GROUP 
   BY  Entity_Id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM