如何进行有条件的加入?

时间:2017-02-10 16:46:54

标签: mysql sql join

这是我的表结构:

// users
+------+----------+ 
|  id  |   name   |
+------+----------+
| 1    | Jack     |
| 2    | Peter    |
| 3    | Ali      |
| 4    | John     |
+------+----------+

posts
+----+-----------+-----------+---------------+-------------------------+
| id | author_id | editor_id |     title     |          content        |
+----+-----------+-----------+---------------+-------------------------+
| 1  | 4         | null      | title1        | content1                |
| 2  | 3         | null      | title2        | content2                |
| 3  | 1         | 3         | title3        | content3                |
| 4  | 3         | null      | title4        | content4                |
| 5  | 2         | null      | title5        | content5                |
| 6  | 2         | 1         | title6        | content6                |
+----+-----------+-----------+---------------+--------------------------+

我试图做的就是在posts表中获取名称而不是ID。所以这是我的疑问:

SELECT p.id,
       p.title, 
       p.content, 
       u1.name AS author_name, 
       u2.name AS editor_name
FROM posts
LEFT JOIN users u1 ON p.author_id = u1.id
LEFT JOIN users u2 ON p.editor_id = u2.id
WHERE p.id = :post_id

好的很好。 我的问题是什么?如您所见,在大多数情况下,editor_id包含null。所以我不需要加入(当它的值为null时)。我的意思是第二次LEFT JOIN不应该在大多数时间内发生。所以我想在第二次加入之前实现这样的条件:

IF ( p.editor_id <> null ) THEN 
   LEFT JOIN users u2 ON p.editor_id = u2.id
ENDIF

我该怎么做?

4 个答案:

答案 0 :(得分:2)

简答:不可能。

<强>为什么:

  • LEFT JOIN的本质本身就是有条件的。它包含“左侧”表中的所有记录,并填充右侧匹配的值,否则在根据连接条件找不到匹配时提供空值。
  • 您在SQL中描述的条件函数可能会创建一个损坏的查询。你不能只从查询中获取整个连接产品,如果它的结果​​在其他地方使用(例如在select参数中),这一点尤为明显。

您尝试做的事情是不必要的,并且不会带来额外的好处。

答案 1 :(得分:1)

我认为您不需要指定NOT NULL条件,即LEFT JOIN的工作方式(无论您是否实现目标)

答案 2 :(得分:1)

如果你真的存在很少的editor_id,我猜你可以在select中使用相关的子查询来获取编辑器的名字。

SELECT p.id,
       p.title, 
       p.content, 
       u1.name AS author_name, 
       (select name from users u where u.id = p.editor_id) as editor_name
FROM posts p
LEFT JOIN users u1 ON p.author_id = u1.id
WHERE p.id = :post_id

答案 3 :(得分:0)

你不能这样做。并且没有必要这样做。

问题 p.editor_id <> null 中显示的条件测试保证评估为NULL,因此它永远不会为TRUE。但即使我们将其改为更合理的 p.editor_id IS NOT NULL ,仍然没有意义。

已经有一个等级谓词,要求u2.id 等于 p.editor_id

这意味着如果p.editor_id为NULL,则相等比较不可能返回TRUE。

它不像数据库引擎会通过用户中的所有行来查找已知的行不存在。

那有什么意义呢?我不明白你想要达到的目的。

您是否试图影响返回的结果集(以获得不同的结果),或者提高性能,或者是什么?

改变这个是有效的:

 LEFT JOIN users u2 ON p.editor_id = u2.id

对此:

 LEFT JOIN users u2 ON p.editor_id = u2.id AND p.editor_id IS NOT NULL

但是添加条件并没有改变任何事情。这是多余的。 p.editor_id = u2.id已经检查p.editor_id不为空;如果它为空,那么它不可能等于u2.id。 (NULL绝不是&#34;等于&#34;对任何东西。)