mysql - 在 MySQL 中连接具有 NULL 值的同一个表

标签 mysql sql

我有一个像这样的简单表格

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),则用户不在结果中

最佳答案

WHEREb.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_idmeta_key 的组合是唯一的(在表 table 中),则 GROUP BY 不是必需的。


在规范的关系模型中,实体的属性被实现为列。作为一个很好的例子,查询返回的结果集看起来很像我们期望的表格。

当在关系数据库中实现实体属性值 (EAV) 模型时,SQL 变得更加复杂。


如果您只想返回具有 colorsize 的 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/

相关文章:

MySql Left join with find_in_set 不能正常工作?

python - 我们可以添加范围作为从数据库中提取值的标准吗?

sql - MySQL MyISAM 表锁定

mysql - 什么相当于 Oracle 数据库的 Number(4) 到 MySQL 数据类型?

mysql - 如何统计MySQL中两个不同表的记录数

sql - 获取字符串中的每个 <tag> - stackexchange 数据库

mysql - 当它引用的字段自动递增时,我如何有效地模仿外键约束?

SQL 字符串格式化程序

javascript - 为菜单系统编写 SQL 查询

MYSQL索引rownum倒序