Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mysql joins and concatenate

I have two tables:

table_a:            table_b
+----+------+    +----+---------+------+
| id | name |    | id | relation| name | 
+----+------+    ++++++---------+------+
| 1  | bob  |    | 1  | friend  | chris|
| 2  | jim  |    | 1  | friend  | jon  |
| 3  | tom  |    | 1  | brother | matt |
+----+------+    | 2  | friend  | sam  |
                 | 2  | parent  | ron  |
                 +----+---------+------+

and I want to enter a query to output something like

+----+------+------------+---------+--------+
| id | name |friend      | brother | parent |
+----+------+------------+---------+--------+
| 1  | bob  | chris, john| matt    |        |
| 2  | jim  | sam        |         |  ron   |
+----+------+------------+---------+--------+

So the id is the comman variable between the two tables, the relation variables have preset values (either friend, brother, parent and maybe a couple other types), and there can be multiple table_b.name per relation per id.

Is this too complicated a task to do?

like image 765
kojitron Avatar asked Oct 23 '12 11:10

kojitron


People also ask

How do you concatenate in a join in SQL?

Another way to implement Concat in SQL with the numerical value is to use the CAST operator. This operator converts the numerical data into the string format. Using the + (plus) operator will manipulate the numeric data into string concatenation.

What are the 4 types of database joins?

Four types of joins: left, right, inner, and outer.

How do you concatenate in MySQL?

CONCAT() function in MySQL is used to concatenating the given arguments. It may have one or more arguments. If all arguments are nonbinary strings, the result is a nonbinary string. If the arguments include any binary strings, the result is a binary string.

Can we use || in MySQL?

The || , operator is a nonstandard MySQL extension. As of MySQL 8.0. 17, this operator is deprecated; expect support for it to be removed in a future version of MySQL. Applications should be adjusted to use the standard SQL OR operator.


1 Answers

SELECT a.ID, a.name,
        GROUP_CONCAT(CASE WHEN relation = 'friend' THEN b.name ELSE NULL END) friend,
        GROUP_CONCAT(CASE WHEN relation = 'brother' THEN b.name ELSE NULL END) brother,
        GROUP_CONCAT(CASE WHEN relation = 'parent' THEN b.name ELSE NULL END) parent
FROM  table_a a
        INNER JOIN table_b b
            ON a.id = b.id
GROUP BY a.ID, a.name

SQLFiddle Demo

in future, if you have any other relation other than friend, brother, and parent and you don't want to alter the query, you can use prepared statement

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'GROUP_CONCAT(CASE WHEN relation = ''',
      relation,
      ''' then b.name ELSE NULL end) AS ',
      relation
    )
  ) INTO @sql
FROM table_b;

SET @sql = CONCAT('SELECT a.ID, a.name, ', @sql, ' 
                   FROM  table_a a
                         INNER JOIN table_b b
                             ON a.id = b.id
                   GROUP BY a.ID, a.name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQLFiddle Demo

like image 197
John Woo Avatar answered Sep 24 '22 07:09

John Woo