Mysql查询在WHERE条件下没有返回结果,但在AND条件下有返回结果

3

这是我使用的查询语句,用于连接两个表:

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 

这是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       |                |
+--------------+------------------------------------------------------------------------

------------+------+-----+---------+----------------+

这是 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,则会返回结果。有什么区别吗? 我很困惑,因为两种方式应该没有区别。


你可能需要在WHERE语句中添加额外的括号来使其工作:((g_metadata.g_id= '2009112305475443' AND g_metadata.value< rf_popup.cardinality) OR g_metadata.g_id IS NULL) - peterm
@peterm 我做了那个,但是没有任何反应。 - shobhit
1个回答

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
  1. A simple join:

    SELECT * 
    FROM TableA 
    LEFT JOIN TableB ON TableA.id = TableB.id
    

    returns

    A.id | B.id | yesNo
    -----+------+------
    1    | 1    | yes
    2    | 2    | no
    3    | 3    | yes
    
  2. Filtering in the ON clause:

    SELECT * 
    FROM TableA 
    LEFT JOIN TableB ON TableA.id = TableB.id
        AND yesNo = 'yes'
    

    returns

    A.id | B.id | yesNo
    -----+------+------
    1    | 1    | yes
    2    | NULL | NULL
    3    | 3    | yes
    
  3. Filtering in the WHERE clause:

    SELECT * 
    FROM TableA 
    LEFT JOIN TableB ON TableA.id = TableB.id
    WHERE yesNo = 'yes'
    

    returns

    A.id | B.id | yesNo
    -----+------+------
    1    | 1    | yes
    3    | 3    | yes
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接