MySQL 合并列
MySQL combine column
我有 2 个 table 相互引用。首先table是位置。
id title
------ --------
001 a
002 b
003 c
004 d
005 e
第二个table是单位
id status info
------ ------ ------------
001 s manager
001 o head manag
002 s programmer
003 s programmer
status字段中,'s'表示header,'o'表示body。
我尝试过左连接,但没有成功。
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)
提前致谢。
您需要按 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
现在,如果您按 id (GROUP BY a.id
) 对结果进行分组但不使用任何聚合函数,MySQL 可以从未列在 GROUP 中的列中自由选择任何值* BY 子句。这对于 title
列** 不是问题,因为它应该始终相同。但对于 header
和 body
列,MySQL 可能会选择 NULL。使用 MIN(...)
我们告诉 MySQL 选择 NOT NULL 的 "smallest" 值(如果只有 NULL "values" 存在则为 NULL)。使用MIN()
或MAX()
都没有关系,因为应该只有一个非空值,结果是一样的。
hedaer:
MIN('manager', NULL) = 'manager'
MAX('manager', NULL) = 'manager'
body:
MIN(NULL, 'head manag') = 'head manag'
MAX(NULL, 'head manag') = 'head manag'
* 事实上它会选择第一个值。但这是一个实施问题,这种行为将来可能会改变。
** 在严格模式下你甚至不允许 select title
因为它没有在 GROUP BY 子句中列出。因此,您要么需要使用聚合函数 (MIN(a.title)
),要么将其列在 GROUP BY 子句中 (GROUP BY a.id, a.title
)。
我有 2 个 table 相互引用。首先table是位置。
id title
------ --------
001 a
002 b
003 c
004 d
005 e
第二个table是单位
id status info
------ ------ ------------
001 s manager
001 o head manag
002 s programmer
003 s programmer
status字段中,'s'表示header,'o'表示body。 我尝试过左连接,但没有成功。
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)
提前致谢。
您需要按 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
现在,如果您按 id (GROUP BY a.id
) 对结果进行分组但不使用任何聚合函数,MySQL 可以从未列在 GROUP 中的列中自由选择任何值* BY 子句。这对于 title
列** 不是问题,因为它应该始终相同。但对于 header
和 body
列,MySQL 可能会选择 NULL。使用 MIN(...)
我们告诉 MySQL 选择 NOT NULL 的 "smallest" 值(如果只有 NULL "values" 存在则为 NULL)。使用MIN()
或MAX()
都没有关系,因为应该只有一个非空值,结果是一样的。
hedaer:
MIN('manager', NULL) = 'manager'
MAX('manager', NULL) = 'manager'
body:
MIN(NULL, 'head manag') = 'head manag'
MAX(NULL, 'head manag') = 'head manag'
* 事实上它会选择第一个值。但这是一个实施问题,这种行为将来可能会改变。
** 在严格模式下你甚至不允许 select title
因为它没有在 GROUP BY 子句中列出。因此,您要么需要使用聚合函数 (MIN(a.title)
),要么将其列在 GROUP BY 子句中 (GROUP BY a.id, a.title
)。