[英]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_id
和meta_key
的組合是UNIQUE(在表table
),則GROUP BY是不必要的。
在規范關系模型中,實體的屬性被實現為列。 很好的例子是,查詢返回的結果集看起來很像我們期望的表。
在關系數據庫中實現實體屬性值(EAV)模型時,SQL變得復雜了一個數量級。
如果您只想返回具有color
或size
的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.