Search code examples
mysqlsqlselectleft-joingroup-concat

MySQL group_concat with join


I have a contact table. Each contact can have multiple phone numbers with different or same table. Similarly each contact can have multiple emails with different or same label. I need to select the all the different phone numbers and email ids belongs to a particular contact.

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' );

I tried GROUP_CONCAT but it is having duplicate entries for the labels.

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


Solution

  • Try this:

    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
    

    Check the SQL FIDDLE DEMO

    OUTPUT

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