我有一个像这样的简单表格
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
怎么办?
答:您需要一个表或内联 View 作为行源,它返回您希望包含在结果集中的每个 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
的行颜色和尺寸的值将折叠起来,您只会获得具有匹配颜色和尺寸的 user_id
值之一。
请注意,如果 user_id
和 meta_key
的组合是唯一的(在表 table
中),则 GROUP BY 不是必需的。
在规范的关系模型中,实体的属性被实现为列。作为一个很好的例子,查询返回的结果集看起来很像我们期望的表格。
当在关系数据库中实现实体属性值 (EAV) 模型时,SQL 变得更加复杂。
如果您只想返回具有 color
或 size
的 user_id 值,您可以使用内联 View (查询 >表
)。此查询与上面相同,但将对 user
表的引用替换为内联 View :
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
关于mysql - 在 MySQL 中连接具有 NULL 值的同一个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24244847/