首页 > 解决方案 > 将不存在的右表值返回为 NULL

问题描述

我有两个 MySQL 表:

CREATE TABLE things (
  id INT
);

CREATE TABLE properties (
  thing_id INT,
  name VARCHAR(100),
  value VARCHAR(100)
);

INSERT INTO things (id) VALUES (1);

INSERT INTO properties (thing_id, name, value) VALUES
  (1, 'name', 'John'),
  (1, 'age', '123');

我希望能够thing根据其名称为 a 选择属性,并NULL在此类属性不存在时返回。这是我尝试过的:

SELECT
  p1.value AS name,
  p2.value AS age,
  p3.value AS foo
FROM
  things AS t
  LEFT JOIN properties AS p1 ON t.id = p1.thing_id
  LEFT JOIN properties AS p2 ON t.id = p2.thing_id
  LEFT JOIN properties AS p3 ON t.id = p3.thing_id
WHERE
  t.id = 1
  AND p1.name = 'name'
  AND p2.name = 'age'
  AND p3.name = 'foo';

我希望结果是

  name |   age | foo
---------------------
'John' | '123' | NULL

但不幸的是,这个查询返回一个空的结果集,因为我认为这样的结果集p3不存在。

我怎样才能写一个查询来做我想做的事?(最好不要使用显式LEFT JOINs 而是逗号和WHERE条件,因为这是一个以编程方式生成的 SQL 查询。)感谢您的任何建议。

标签: mysqlsql

解决方案


您需要将WHERE条件移到p1, p2p3它们各自的JOIN条件中,否则会将这些LEFT JOINs 变成INNER JOINs (请参阅手册)。

SELECT
  p1.value AS name,
  p2.value AS age,
  p3.value AS foo
FROM
  things AS t
  LEFT JOIN properties AS p1 ON t.id = p1.thing_id AND p1.name = 'name'
  LEFT JOIN properties AS p2 ON t.id = p2.thing_id AND p2.name = 'age'
  LEFT JOIN properties AS p3 ON t.id = p3.thing_id AND p3.name = 'foo'
WHERE
  t.id = 1

推荐阅读