连接3个表,其中一个表行成为列

时间:2016-07-01 19:06:46

标签: mysql database

我会尽力解释我的目标:

3桌 -

从用户中选择*;

+--------+----------+
|   id   | firstname|
+--------+----------+
|    1   |  John    |    
|    2   |  Mary    |
+--------+----------+

从链接中选择*;

+--------+---------+-----------------+
|user_id | link_id | viewname        |
+--------+---------+-----------------+
|   1    |   11    | John and Jane   |
|   2    |   13    | Mary and Mike   |
+--------+---------+-----------------+

从值中选择*;

+--------+----------+-----------+
|link_id |value_id  |link_value |
+--------+----------+-----------+
|   11   |   2      |  Image1   |
|   11   |   5      |  Steak    |
|   13   |   5      |  Chicken  |
|   11   |   3      |  Blue     |
|   11   |   4      |  Option1  |
|   13   |   1      |  Yes      |
|   13   |   2      |  Image2   |
|   13   |   4      |  Option1  |
|   13   |   3      |  Green    |
|   11   |   1      |  No       |
+--------+----------+-----------+

我的目标是加入这三个表,并使value_id的内容成为列标题。像这样 -

+------------+---------------+------+--------+---------+---------+---------+
| firstname  |    viewname   |   1  |   2    |    3    |   4     |   5     |    
+------------+---------------+------+--------+---------+---------+---------+
|   John     | John and Jane |  No  | Image1 |   Blue  | Option1 | Steak   |
|   Mary     | Mike and Mary |  Yes | Image2 |   Green | Option1 | Chicken |
+------------+---------------+------+--------+---------+---------+---------+

MySQLfiddle

我尝试过并尝试过失败。此时的任何帮助/建议都将不胜感激。

1 个答案:

答案 0 :(得分:0)

对于此示例数据,您可以尝试以下查询;)

select 
    u.firstname, l.viewname,
    max(if(lv.value_id = 1, lv.`value`, '')) as `1`,
    max(if(lv.value_id = 2, lv.`value`, '')) as `2`,
    max(if(lv.value_id = 3, lv.`value`, '')) as `3`,
    max(if(lv.value_id = 4, lv.`value`, '')) as `4`,
    max(if(lv.value_id = 5, lv.`value`, '')) as `5`
from users u
inner join links l
on u.`id` = l.`user_id`
inner join link_value lv
on l.link_id = lv.link_id
group by u.firstname, l.viewname

SQLFiddle Demo

如果你有value_id的动态值,你必须创建一个动态的sql来执行此操作,例如:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(IF(lv.value_id = ',
      value_id,
      ', lv.`value`, '''')) AS `',
      value_id, '`'
    ) ORDER BY value_id
  ) INTO @sql
FROM link_value
;
SET @sql = CONCAT('SELECT u.firstname, l.viewname, ', @sql,
                  ' FROM users u
                   INNER JOIN links l
                   ON u.`id` = l.`user_id`
                   INNER JOIN link_value lv
                   ON l.link_id = lv.link_id
                   GROUP BY u.firstname, l.viewname');

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

SQLFiddle Demo