Question

i have a mySQL table set up like this

+----+----------+---------+
| id | parentid | content |
+----+----------+---------+
| 1  | 0        | a       |
| 2  | 1        | b       |
| 3  | 0        | c       |
| 4  | 3        | d       |
| 5  | 3        | e       |
| 6  | 3        | f       |
+----+----------+---------+

what i would like to do is concatenate the content of the children onto the end of the parent (then delete the children, but i will do that later), in ASC order based on id. so the result should look like this (without children)

+----+----------+---------+
| id | parentid | content |
+----+----------+---------+
| 1  | 0        | ab      |
| 3  | 0        | cdef    |    
+----+----------+---------+

the issue im running into is that as you can see a parent may have more than one child. so far the query i have is

UPDATE table 
SET content = CONCAT(content, 
...
) ORDER BY id ASC

im not sure what to place in the ... section to grab all of the children and append them in order they were retrieved. maybe im going about it the wrong way. any help will be greatly appreciated

Was it helpful?

Solution

One option is:

/*Table structure for table `table` */

DROP TABLE IF EXISTS `table`;

CREATE TABLE `table` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `parentid` INT(11) UNSIGNED NOT NULL,
  `content` VARCHAR(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB;

/*Data for the table `table` */

INSERT  INTO `table`(`parentid`,`content`)
VALUES
(0,'a'),(1,'b'),(0,'c'),(3,'d'),(3,'e'),(3,'f');

UPDATE `table`
    INNER JOIN
    (SELECT `t0`.`id`, CONCAT(`t0`.`content`, GROUP_CONCAT(`t1`.`content` SEPARATOR '')) AS `content`
     FROM `table` `t0`
        INNER JOIN `table` `t1` ON `t0`.`id` = `t1`.`parentid`
     WHERE `t0`.`parentid` = 0
     GROUP BY `t1`.`parentid`) `der`
SET `table`.`content` = `der`.`content`
WHERE `table`.`id` = `der`.`id`;

DELETE FROM `table` WHERE `parentid` > 0;

SQL Fiddle demo

OTHER TIPS

You have to perfom so much changes to the table that it might be better to create another one with the new data and drop the current one.

The query that will get you the results you're looking for is:

SELECT
  min(t1.id) id,
  0 parentid,
  group_concat(t1.content ORDER BY t1.id separator '') content
FROM t t1
LEFT JOIN t t2 ON t1.parentid = t2.id
GROUP BY coalesce(t2.id, t1.id);

Fiddle here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top