这是我用来连接两个表的查询
SELECT `rf_popup`.*
FROM `rf_popup` LEFT JOIN
`g_metadata` ON (`rf_popup`.`name` = `g_metadata`.`name`)
WHERE (`g_metadata`.`g_id` = '2009112305475443' AND
`g_metadata`.`value` < rf_popup.cardinality OR
`g_metadata`.`g_id` IS NULL) AND
`category` IN ('S', 'all') AND
`field` IN ('descr', 'all') AND
`filler_type` IN ('F2', 'all')
ORDER BY `rf_popup`.`priority` DESC LIMIT 5
这是TABLE rf_popup
+--------------+------------------------------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------------------------------------------------------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(200) | YES | | NULL | |
| text | text | YES | | NULL | |
| cardinality | int(11) | NO | | 1 | |
| field | varchar(200) | YES | | NULL | |
| category | enum('A','H','N','R','S','D','all') | YES | | NULL | |
| time_to_show | enum('START','END') | YES | | START | |
| filler_type | enum('F1','F2','F3','R1','R2','R3','all') | YES | | FILLER1 | |
| priority | int(11) | NO | | 0 | |
+--------------+------------------------------------------------------------------------
------------ + ------ + ----- + --------- + ----------- ----- +
这是TABLE g_metadata
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| g_id | varchar(50) | YES | MUL | NULL | |
| name | varchar(50) | YES | MUL | NULL | |
| value | varchar(200) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------+--------------+------+-----+---------+----------------+
但是查询返回空结果。但是如果我用WHERE
替换查询中的AND
。查询返回结果。差异是什么?
应该没有任何区别,所以我很困惑
答案 0 :(得分:2)
简单来说,WHERE
过滤整个结果集和JOIN ... ON
仅过滤联接的表格。
由于此处有LEFT JOIN
,因此将过滤器放在ON
子句中会限制为g_metadata
表返回的结果,但不会影响为rf_popup
返回的结果}。也就是说,您将在连接表(g_metadata
)中获得空列,但仍会提取rf_popup
的行。
另一方面,将过滤器放在WHERE
子句中首先执行连接,然后过滤生成的(连接的)结果集。也就是说,不会返回与整个WHERE
子句不匹配的行。
考虑以下简化示例:
TableA: id ----- 1 2 3 TableB: id | yesNo -----+------ 1 | yes 2 | no 3 | yes
简单加入:
SELECT *
FROM TableA
LEFT JOIN TableB ON TableA.id = TableB.id
返回
A.id | B.id | yesNo -----+------+------ 1 | 1 | yes 2 | 2 | no 3 | 3 | yes
过滤ON
子句:
SELECT *
FROM TableA
LEFT JOIN TableB ON TableA.id = TableB.id
AND yesNo = 'yes'
返回
A.id | B.id | yesNo -----+------+------ 1 | 1 | yes 2 | NULL | NULL 3 | 3 | yes
过滤WHERE
子句:
SELECT *
FROM TableA
LEFT JOIN TableB ON TableA.id = TableB.id
WHERE yesNo = 'yes'
返回
A.id | B.id | yesNo -----+------+------ 1 | 1 | yes 3 | 3 | yes