簡體   English   中英

在MySQL中使用NULL值聯接同一表

[英]Joining same table with NULL values in 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),則用戶不在結果中

WHERE b.meta_key上的謂詞否定了LEFT 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值。 例如,如果您有一個名為“ users”的表,每個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任何行都將折疊,並且您將僅獲得與color和size匹配的user_id值之一尺寸。

請注意,如果user_idmeta_key的組合是UNIQUE(在表table ),則GROUP BY是不必要的。


在規范關系模型中,實體的屬性被實現為列。 很好的例子是,查詢返回的結果集看起來很像我們期望的表。

在關系數據庫中實現實體屬性值(EAV)模型時,SQL變得復雜了一個數量級。


如果您只想返回具有colorsize的user_id值,則可以獲取帶有內聯視圖的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

where子句殺死了您。 讓我們采用b.meta_key = 'size' 如果您的B表中沒有行,則meta_key將返回null。 該列上的過濾器會將它們從結果中刪除。 嘗試將b.meta_key = 'size'到on子句中。

嘗試以下代碼,

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'
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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM