我有一个像
这样的简单表格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),则用户不在结果中
答案 0 :(得分:2)
b.meta_key
中的WHERE
上的谓词否定了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
怎么办?
A:您需要一个表或内联视图作为行源,返回您希望包含在结果集中的每个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
的组合为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
答案 1 :(得分:1)
where子句会杀了你。我们来看b.meta_key = 'size'
。如果B表中没有行,则meta_key将返回null。该列上的过滤器将其从结果中删除。尝试将b.meta_key = 'size'
添加到on子句中。
答案 2 :(得分: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'
答案 3 :(得分: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')