2012-03-27 38 views
3

我有兩個表。我怎樣才能讓一個WHERE子句僅適用於右表在左加入?

TableA: field_definitions 
field_id, field_type, field_length, field_name, field_desc, display_order, field_section, active 

TableB: user_data 
response_id, user_id, field_id, user_response 

我需要一個查詢,從表一返回所有行,如果存在的話,基於特定的user_id匹配從表B中的行。

這裏是我迄今爲止...

SELECT field_definitions. * , user_data.user_response 
FROM field_definitions 
LEFT JOIN user_data 
USING (field_id) 
WHERE (
user_data.user_id =8 
OR user_data.user_id IS NULL 
) 
AND field_definitions.field_section =1 
AND field_definitions.active =1 
ORDER BY display_order ASC 

這隻能如果表B中的行數爲零或匹配行的WHERE子句中的USER_ID。如果表B具有匹配field_id但不包含user_id的行,則返回的行數爲零。

本質上,一旦在表B中的行對用戶X存在,所述查詢不再從表A中搜索使用者z的反應和沒有時發現返回行。

我需要的結果總是包含從表格中的行,即使有B中沒有匹配的行用正確的USER_ID。

+0

你的規格是不明確的。目前不考慮表B,是否希望:a)返回表A中的所有行; b)基於特定的user_id返回表A中的所有行; c)別的東西? – onedaywhen 2012-03-27 07:29:34

+0

@onedaywhen我認爲最後一段總結了它,我總是希望從A返回的行和可選地匹配B行的條件,他們是爲正確的用戶 – Corey 2012-03-27 14:24:18

回答

10

可以移動從WHERE條款這些約束到ON條款(這首先要求你改變USING條款爲ON條款:ON條款比USING條款更靈活)。因此:

SELECT field_definitions.*, 
     user_data.user_response 
    FROM field_definitions 
    LEFT 
    JOIN user_data 
    ON user_data.field_id = field_definitions.field_id 
    AND user_data.user_id = 8 
WHERE field_definitions.field_section = 1 
    AND field_definitions.active = 1 
ORDER 
    BY field_definitions.display_order ASC 
; 
3

從概念上講,首先執行連接,然後將where子句應用於虛擬結果集。如果你想先過濾一個表,你必須代碼爲內子選擇加入。沿着這些路線的東西:

SELECT 
    field_definitions. * , 
    user8.user_response 
FROM 
    field_definitions 
    LEFT JOIN (select * from user_data where user_id=8 or user_id is null) as user8 
    USING (field_id) 
WHERE 
    field_definitions.field_section =1 
    AND field_definitions.active =1 
ORDER BY display_order ASC 
+0

我得到「#1248 - 每個派生表必須有它自己的別名「與此 – Corey 2012-03-27 14:26:16

+0

我忘了包括一個表別名...答覆編輯。 – 2012-03-27 18:27:25

1

你可以在裏面移動在WHERE子句如下

SELECT field_definitions. * , user_data.user_response 
FROM (
    select * from 
    field_definitions 
    WHERE field_definitions.field_section =1 
    AND field_definitions.active =1) as field_definitions 
LEFT JOIN (
    select * from 
    user_data 
    where user_data.user_id =8 
    OR user_data.user_id IS NULL) as user_data 
USING (field_id) 
ORDER BY display_order ASC 
0

的SEPC的直譯:

SELECT field_definitions. * , '{{MISSING}}' AS user_response 
    FROM field_definitions 
UNION 
SELECT field_definitions. * , user_data.user_response 
    FROM field_definitions 
     NATURAL JOIN user_data 
WHERE user_data.user_id = 8; 

不過,我懷疑你不真的很想「表A的所有行」。

相關問題