我有两个相互引用的表。第一张表是位置。
id title
------ --------
001 a
002 b
003 c
004 d
005 e
,第二个表是单位。
id status info
------ ------ ------------
001 s manager
001 o head manag
002 s programmer
003 s programmer
在状态栏中,' s'表示标题,' o'意味着身体。 我尝试过没有运气的左连接。
SELECT a.id, a.title,
(CASE WHEN b.status = 's' THEN b.info END) AS header,
(CASE WHEN b.status = 'o' THEN b.info END) AS body
FROM
POSITION a LEFT JOIN
unit b
ON a.id = b.id
结果是
id title header body
------ ------ ---------- ------------
001 a manager (NULL)
001 a (NULL) head manag
002 b programmer (NULL)
003 c programmer (NULL)
我想知道结果是这样的
id title header body
------ ------ ---------- ------------
001 a manager head manag
002 b programmer (NULL)
003 c programmer (NULL)
提前感谢。
答案 0 :(得分:0)
您需要GROUP BY ID。并且您需要状态列的聚合函数(如MIN()
或MAX()
)。
SELECT a.id, a.title,
MIN(CASE WHEN b.status = 's' THEN b.info END) AS header,
MIN(CASE WHEN b.status = 'o' THEN b.info END) AS body
FROM
POSITION a LEFT JOIN
unit b
ON a.id = b.id
GROUP BY a.id
<强>更新强>
让我们在没有聚合的情况下获取您的原始结果,但仅将其限制为id = 001
id title header body
------ ------ ---------- ------------
001 a manager (NULL)
001 a (NULL) head manag
现在,如果按结果(GROUP BY a.id
)对结果进行分组,但不使用任何聚合函数,MySQL可以自由地从GROUP BY子句中未列出的列中选择任何值*。这不是title
列**的问题,因为它应该始终相同。但对于header
和body
列,MySQL可能会选择NULL。使用MIN(...)
我们告诉MySQL选择&#34;最小的&#34;值为NOT NULL(如果只有NULL和#34,则为NULL;值为#34;存在)。使用MIN()
或MAX()
并不重要,因为只应该有一个非空值,结果将是相同的。
hedaer:
MIN('manager', NULL) = 'manager'
MAX('manager', NULL) = 'manager'
body:
MIN(NULL, 'head manag') = 'head manag'
MAX(NULL, 'head manag') = 'head manag'
<小时/> *实际上它会选择第一个值。但这是一个实施问题,将来可能会改变这种行为。
**在严格模式下,您甚至不允许选择title
,因为它未在GROUP BY子句中列出。因此,您需要使用聚合函数(MIN(a.title)
)或在GROUP BY子句(GROUP BY a.id, a.title
)中列出它。