看不懂mysql自左连接查询

问题描述 投票:0回答:1

我遇到一个查询是,

SELECT it1.survey_set_id, it1.type, it1.value FROM survey_condition_filter it1 LEFT JOIN survey_condition_filter it2 ON(it1.survey_set_id = it2.survey_set_id AND it2.type = 3002) WHERE it1.type IN (2000, 2001, 2002) AND it2.value IS NULL;

为什么在上面的查询中使用self left-join。

SELECT survey_set_id, type, value FROM survey_condition_filter WHERE type IN (2000, 2001, 2002);

上面的查询不等同于第一个使用自左连接的查询。因为查询也只是过滤

IN (2000, 2001, 2002) AND it2.value IS NULL
。我对这里连接查询的使用感到困惑,无法真正理解第一个查询的工作原理。

这是表格survey_condition_filter

+---------------+--------------+------+-----+---------+-------+
| Field         | Type         | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| survey_id     | bigint       | NO   | PRI | NULL    |       |
| survey_set_id | bigint       | NO   | PRI | NULL    |       |
| type          | int          | NO   | PRI | NULL    |       |
| condition     | tinyint      | NO   | PRI | NULL    |       |
| value         | varchar(15)  | NO   | PRI | NULL    |       |
| display_value | text         | NO   |     | NULL    |       |
| order         | int          | YES  |     | NULL    |       |
| created_at    | datetime     | NO   |     | NULL    |       |
| created_by    | varchar(255) | YES  |     | NULL    |       |
| updated_at    | datetime     | NO   |     | NULL    |       |
| updated_by    | varchar(255) | YES  |     | NULL    |       |
| deleted_at    | datetime     | YES  |     | NULL    |       |
| deleted_by    | varchar(255) | YES  |     | NULL    |       |
+---------------+--------------+------+-----+---------+-------+
mysql left-join self-join
1个回答
0
投票

这是一个反加入。我们外连接一个表,但只保留外连接的行(通过在这里应用

WHERE ... it2.value IS NULL
)。使用直截了当的
NOT EXISTS
(或在许多情况下为
NOT IN
)更常见——在我看来也更具可读性。

SELECT it1.survey_set_id, it1.type, it1.value
FROM survey_condition_filter it1 
WHERE it1.type IN (2000, 2001, 2002) 
AND NOT EXISTS
(
  SELECT null
  FROM survey_condition_filter it2 
  WHERE it2.survey_set_id = it1.survey_set_id
  AND it2.type = 3002
);

此查询的作用很明显:选择所有类型为 2000/2001/2002 的行,其中不存在相同的 survey_set_id 的 3002 行。

如果 survey_set_id 是不可为 null 的列,您可以使用

NOT IN
,这会使查询更短:

SELECT it1.survey_set_id, it1.type, it1.value
FROM survey_condition_filter it1 
WHERE it1.type IN (2000, 2001, 2002) 
AND itl.survey_set_id NOT IN
(
  SELECT it2.survey_set_id
  FROM survey_condition_filter it2 
  WHERE it2.type = 3002
);
© www.soinside.com 2019 - 2024. All rights reserved.