MySQL组合列

时间:2016-09-17 12:21:33

标签: mysql join left-join

我有两个相互引用的表。第一张表是位置。

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)  

提前感谢。

1 个答案:

答案 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

sqlfiddle

<强>更新

让我们在没有聚合的情况下获取您的原始结果,但仅将其限制为id = 001

id      title   header      body        
------  ------  ----------  ------------
001     a       manager     (NULL)      
001     a       (NULL)      head manag  

现在,如果按结果(GROUP BY a.id)对结果进行分组,但不使用任何聚合函数,MySQL可以自由地从GROUP BY子句中未列出的列中选择任何值*。这不是title列**的问题,因为它应该始终相同。但对于headerbody列,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)中列出它。