2014-06-16 36 views
0

我有一個簡單的表像加入同桌NULL值在MySQL

user_id | meta_key | meta_value 
=============================== 
    1 | color | green 
    2 | color | red 
    1 | size  | L 
    2 | size  | L 
    3 | color | blue 

... 

現在我喜歡一個查詢在那裏我得到某個用戶的所有顏色和大小

SELECT a.user_id AS ID, a.meta_value AS color, b.meta_value AS size 
    FROM table AS a 
    LEFT JOIN table AS b ON a.user_id = b.user_id 
WHERE a.meta_key = 'color' AND b.meta_key = 'size' GROUP BY a.meta_value, b.meta_value 

該作品只要我有一個size爲每個用戶。如果size缺少(ID 3的示例中)的用戶是不是在結果

回答

2

WHEREb.meta_key謂詞是否定的LEFT的「outerness」 JOIN操作。

一種選擇是,該謂詞搬遷到ON條款,例如:

SELECT a.user_id AS ID, a.meta_value AS color, b.meta_value AS size 
    FROM table AS a 
    LEFT JOIN table AS b ON a.user_id = b.user_id 
     AND b.meta_key = 'size' 
WHERE a.meta_key = 'color' GROUP BY a.meta_value, b.meta_value 

隨訪

問:如果color不見了?

答:你需要一個表或內聯視圖作爲一個行源,它返回你想包含在結果集中的每個值user_id。例如,如果你有一臺名爲「用戶」,每user_id一行,並希望每一個id該表中返回:

SELECT u.id   AS user_id 
     , a.meta_value AS color 
     , b.meta_value AS size 
    FROM user u 
    LEFT 
    JOIN `table` a 
    ON a.user_id = u.id 
    AND a.meta_key = 'color' 
    LEFT 
    JOIN `table` b 
    ON b.user_id = u.id 
    AND b.meta_key = 'size' 
    GROUP 
    BY u.id 
     , a.meta_value 
     , b.meta_value 

我們還注意到,在您的原始查詢的GROUP BY做不包括user_id列,因此任何具有相同顏色和大小的meta_value的行都將摺疊,並且只會獲得具有匹配顏色和大小的user_id值之一。

請注意,如果user_idmeta_key的組合是UNIQUE(在表table中),那麼GROUP BY不是必需的。


在規範的關係模型中,實體的屬性實現爲列。作爲一個很好的例子,查詢返回的結果集看起來很像我們期望的表。

當在關係數據庫中實現實體屬性值(EAV)模型時,SQL的數量級變得更加複雜。


如果你想返回USER_ID的值只能是要麼colorsize,你可以得到的user_id值的列表與內嵌視圖(針對table查詢)。該查詢與上面相同,但有一個內嵌視圖替換參考user表:

SELECT u.id   AS user_id 
     , a.meta_value AS color 
     , b.meta_value AS size 
    FROM (SELECT t.user_id AS id 
      FROM table t 
      WHERE t.meta_key IN ('color','size') 
      GROUP BY t.user_id 
     ) u 
    LEFT 
    JOIN `table` a 
    ON a.user_id = u.id 
    AND a.meta_key = 'color' 
    LEFT 
    JOIN `table` b 
    ON b.user_id = u.id 
    AND b.meta_key = 'size' 
    GROUP 
    BY u.id 
     , a.meta_value 
     , b.meta_value 
+0

OK,如果'color'缺什麼? – Xaver

+0

@revaxarts:你需要一個「user_id」列的「源」,一個表或內聯視圖,保證返回你想要返回的每個'user_id'的值。我會通過後續更新我的答案。 – spencer7593

+0

感謝您的回答。當顏色和大小都退出時,我想到了這個問題。在我的情況下,我根本不需要這個條目,所以第一個答案是正確的 – Xaver

1

WHERE子句殺了你。我們以b.meta_key = 'size'。如果B表中沒有行,則meta_key將返回空值。該列上的過濾器將其從結果中刪除。嘗試將b.meta_key = 'size'添加到on子句。

0

試試下面的代碼,

SELECT a.user_id AS ID, a.meta_value AS color, b.meta_value AS size FROM table AS a where a.meta_key = 'color' or a.meta_key = 'size' 
0
SELECT a.user_id AS ID, 
a.meta_value AS color, b.meta_value AS size 
FROM table AS a 
LEFT JOIN table AS b ON a.user_id = b.user_id 
WHERE a.meta_key in ('Color', 'Size')