3

これは、2つのテーブルを結合するために使用しているクエリです

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

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

これは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. クエリは結果を返します。違いは何ですか?? 違いはないはずなので、混乱しています

4

1 に答える 1

2

簡単に言えば、結果セット全体WHEREフィルタリングし、結合されたテーブルのみをフィルタリングします。JOIN ... ON

LEFT JOINhereがあるため、ON句にフィルターを配置すると、テーブルに対して返される結果が制限されg_metadataますが、 に対して返される結果には影響しませんrf_popup。つまり、結合されたテーブル ( g_metadata) に null 列が表示されますが、行rf_popupは引き続きプルされます。

一方、フィルターをWHERE句に入れると、最初に結合が実行され、次に結果の (結合された) 結果セットがフィルター処理されます。つまり、WHERE句全体に一致しない行は返されません。


次の簡単な例を検討してください。

表A:

ID
-----
1
2
3

表 B:

ID | はい・いいえ
---+------
1 | はい
2 | 番号
3 | はい
  1. 簡単な結合:

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

    戻り値

    A.id | B.id | はい・いいえ
    ---+------+------
    1 | 1 | はい
    2 | 2 | 番号
    3 | 3 | はい
    
  2. ON節でのフィルタリング:

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

    戻り値

    A.id | B.id | はい・いいえ
    ---+------+------
    1 | 1 | はい
    2 | ヌル | ヌル
    3 | 3 | はい
    
  3. WHERE節でのフィルタリング:

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

    戻り値

    A.id | B.id | はい・いいえ
    ---+------+------
    1 | 1 | はい
    3 | 3 | はい
    
于 2013-01-30T06:03:52.463 に答える