MySQL group_concat 与连接
Posted
技术标签:
【中文标题】MySQL group_concat 与连接【英文标题】:MySQL group_concat with join 【发布时间】:2015-02-25 13:37:28 【问题描述】:我有一张联系表。每个联系人可以有多个电话号码,具有不同或相同的表。同样,每个联系人可以拥有多封具有不同或相同标签的电子邮件。我需要选择属于特定联系人的所有不同电话号码和电子邮件 ID。
CREATE TABLE IF NOT EXISTS `contact` (
`id` int(8) unsigned NOT NULL ,
`fname` varchar(64) NOT NULL,
`lname` varchar(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE IF NOT EXISTS `phone` (
`id` int(8) unsigned NOT NULL ,
`sourceid` int(8) unsigned NOT NULL ,
`type` varchar(16) NOT NULL,
`phone` varchar(16) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE IF NOT EXISTS `email` (
`id` int(8) unsigned NOT NULL ,
`sourceid` int(8) unsigned NOT NULL ,
`type` varchar(16) NOT NULL,
`email` varchar(128) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
INSERT INTO contact values ( 1,'john' ,'j' ),
(2, 'jose' ,'f' ),
(3, 'test' ,'k' ),
(4, 'tester' ,'j' );
INSERT INTO phone values( 1 ,1, 'Home', '123456' ),
( 2 ,1, 'Home', '123456342' ),
( 3 ,1, 'Office', '12345645' ),
( 4 ,1, 'Mobile', '1234567' ),
( 5 ,2, 'Home', '123456' ),
( 5 ,2, 'Home', '987556' );
INSERT INTO email values
( 1 ,1, 'Home', 'john@gmail.com' ),
( 2 ,1, 'Home', 'john@yahoo.com' ),
( 3 ,1, 'Office', 'john@inc.com' ),
( 4 ,2, 'Home', 'jose@gmail.com' ),
( 5 ,4, 'Home', 'test@test.com' );
我尝试了 GROUP_CONCAT,但它的标签条目重复。
SELECT C.id, fname, lname
, GROUP_CONCAT(ph.sourceid),
GROUP_CONCAT(em.sourceid),
GROUP_CONCAT(ph.type), GROUP_CONCAT(ph.phone),
GROUP_CONCAT(em.type), GROUP_CONCAT(em.email)
FROM contact AS C
LEFT JOIN phone AS PH ON PH.sourceid = C.id
LEFT JOIN email EM ON EM.sourceid = C.id
WHERE C.id='1'
GROUP BY C.id
SQL FIDDLE
【问题讨论】:
【参考方案1】:试试这个:
SELECT c.id, c.fname, c.lname,
ph.PhoneType, ph.PhoneNos,
em.EmailType, em.EmailIds
FROM contact AS c
LEFT JOIN (SELECT ph.sourceid, GROUP_CONCAT(ph.type) AS PhoneType, GROUP_CONCAT(ph.phone) AS PhoneNos
FROM phone AS ph
GROUP BY ph.sourceid
) AS ph ON ph.sourceid = c.id
LEFT JOIN (SELECT em.sourceid, GROUP_CONCAT(em.type) AS EmailType, GROUP_CONCAT(em.email) AS EmailIds
FROM email AS em
GROUP BY em.sourceid
) AS em ON em.sourceid = c.id
WHERE c.id = '1'
GROUP BY c.id
查看SQL FIDDLE DEMO
输出
| ID | FNAME | LNAME | PHONETYPE | PHONENOS | EMAILTYPE | EMAILIDS |
|----|-------|-------|-------------------------|-----------------------------------|------------------|--------------------------------------------|
| 1 | john | j | Home,Home,Office,Mobile | 123456,123456342,12345645,1234567 | Home,Home,Office | john@gmail.com,john@yahoo.com,john@inc.com |
【讨论】:
对不起,我忘了说我也需要标签(类型)。如果我添加 DISTINCT,则不会选择不同的标签。 SELECT C.id, fname, lname, GROUP_CONCAT(DISTINCT ph.phone), GROUP_CONCAT(DISTINCT em.email) ,GROUP_CONCAT(DISTINCT em.type) FROM contact AS C LEFT JOIN phone AS PH ON PH.sourceid = C.id LEFT JOIN email AS EM ON EM.sourceid = C.id WHERE C.id = '1' GROUP BY C.id 这将返回电子邮件类型 Home 和 Office,但有两个 Home 类型的电子邮件在表中以上是关于MySQL group_concat 与连接的主要内容,如果未能解决你的问题,请参考以下文章
mysql中的group_concat与“case when”条件