Mysql 什么样的联接可以看到联接表中不存在的值?

Mysql 什么样的联接可以看到联接表中不存在的值?,mysql,Mysql,我有表用户,位置和联接表。联接表在该位置的每个个体也有一个秩值,因为这些个体在某些位置的秩高于其他位置的秩 users ========= id | name ========= 1 | john 2 | bob 3 | alex locations =============== id | name =============== 1 | san diego 2 | dallas 3 | new york 4 | denver join_users_locations ===

我有表
用户
位置
和联接表。联接表在该位置的每个个体也有一个秩值,因为这些个体在某些位置的秩高于其他位置的秩

users
=========
id | name
=========
 1 | john
 2 | bob
 3 | alex

locations
===============
id | name
===============
 1 | san diego
 2 | dallas
 3 | new york
 4 | denver

join_users_locations
==============================
user_id | location_id | rank
==============================
      2 |           1 | 4
      2 |           2 | 3
      2 |           4 | 2
      3 |           1 | 2
      3 |           2 | 4
您可以看到,在联接表中,仅当用户在该位置具有排名时,才会列出该用户。如果它们的秩为零/空,则它们不在表中

我希望得到如下查询结果:

name |  location | rank 
=======================
 bob | san diego | 4
 bob |    dallas | 3
 bob |  new york | 0
 bob |    denver | 2
如您所见,我希望所有位置都在列表中,即使是用户未加入的位置(只需将这些字段的秩值设置为零)

很容易获得他/她加入的地点和等级列表:

SELECT
    u.name,
FROM users u
LEFT JOIN join_users_locations jul ON jul.user_id = u.id
LEFT JOIN locations l ON l.id = jul.location_id
WHERE u.id = 2
但这只列出了用户加入的位置。我还想查看未连接的位置

我知道这是可能的,但我不确定解决方案是什么。我尝试了一些不同类型的联接,得到了不同的结果

左外连接。外部联接包括联接“左侧”的所有内容,即使左侧没有对应的元组。不过,您可能会得到null而不是0。可以吗? (如果不是,您可以将空值显示设置为0)

您可以使用从
用户
位置
执行此操作

SELECT
    u.name,
    l.name AS location,
    IFNULL(jul.rank, 0) AS rank
FROM
    users u CROSS JOIN
    locations l LEFT JOIN
    join_users_locations jul 
        ON jul.user_id = u.ID 
        AND jul.location_id = l.id
WHERE u.id = 2


啊,有趣。。。以前从未使用过交叉连接。让它在这里完美工作:感谢where子句中的隐式连接将具有与内部连接相同的效果。。。jul.rank将永远不会为空,并且这不能返回用户在
加入用户位置中没有记录的任何位置。
…这对你们来说非常复杂…:)不过,您插入的所有值都有等级。如果我将其中一个插入更改为秩为null并重新运行它,我将得到您想要的结果。除了空白而不是0。我没听懂。你能复制/粘贴SQL Fiddle url吗?顺便说一句,交叉连接相当于左外连接和右外连接。@collen不是学究,而是
左外连接和
右外连接是
完全连接
,而不是
交叉连接
。。。
交叉连接
是一种连接。
SELECT u.name,l.name as location,jul.rank
FROM users u,locations l,join_users_locations jul
WHERE u.id = jul.user_id AND
      jul.location_id = l.id AND
      u.id = 2
UNION
SELECT 'bob' AS NAME,A.NAME AS location,A.RANK_NULL AS RANK
FROM
(SELECT *,IFNULL(RANK,0) AS RANK_NULL
FROM (SELECT * FROM JOIN_USERS_LOCATIONS JUL WHERE JUL.USER_ID=2 )JUL
RIGHT JOIN LOCATIONS L
   ON JUL.LOCATION_ID = L.ID
WHERE RANK IS NULL)A
 SELECT IFNULL(JUL.NAME,'bob'),L.NAME,IFNULL(RANK,0) AS RANK
FROM  (SELECT U.NAME,JUL.USER_ID,JUL.LOCATION_ID,JUL.RANK 
       FROM USERS U,JOIN_USERS_LOCATIONS JUL 
       WHERE U.ID=JUL.USER_ID AND JUL.USER_ID=2 
      ) JUL
      RIGHT JOIN 
      LOCATIONS L
   ON JUL.LOCATION_ID = L.ID