mysql join,group_concat和group by

时间:2013-01-06 09:01:13

标签: mysql sql foreach pivot

我有usersinductionsuser_inductions的表格。

  • users表包含idname
  • inductions表格包含idname以及
  • user_inductionsiduser_idinduction_id

我想返回所有导入列表和已完成导入的人员列表。我已经这样做了,因为我希望创建一个如下表格。我不确定如何编辑查询,因此我可以按照自己的意愿获取信息。

------------------------------------------------------------------------------------
| name    | tennis | cricket | rugby | squash | football | Table tennis |   etc    |
------------------------------------------------------------------------------------
| Bob     |   0    |   1     |   0   |    1   |    1     |     0        |          |
------------------------------------------------------------------------------------
| paul    |   1    |   1     |   1   |    1   |    0     |     0        |          |
------------------------------------------------------------------------------------

我想循环访问数据,以便在顶部获取导入列表,然后每个用户如果已经在该主题上导入,则为1,如果不是,则为0。我有几个查询,但他们只返回所有用户只有他们已经完成的导入或导入和那些已经完成它们的人。

例如:

SELECT CONCAT(  `f_name` ,  ' ',  `l_name` ) AS user, GROUP_CONCAT( pmainductions.name
ORDER BY pmainductions.id ) AS induction
FROM users
LEFT JOIN pmainduction_user ON users.id = pmainduction_user.user_id
LEFT JOIN pmainductions ON pmainductions.id = pmainduction_user.pmainduction_id
GROUP BY users.id

这会产生

bob | cricket,squash,football

paul| tennis,cricket,rugby,squash

任何帮助将不胜感激。谢谢:))

1 个答案:

答案 0 :(得分:2)

试试这个:

SELECT 
  CONCAT(  `f_name` ,  ' ',  `l_name` ) AS user, 
  MAX(CASE WHEN pmainductions.name = 'tennis' THEN 1 ELSE 0 END) AS 'tennis',
  MAX(CASE WHEN pmainductions.name = 'cricket' THEN 1 ELSE 0 END) AS 'cricket',
  MAX(CASE WHEN pmainductions.name = 'rugby' THEN 1 ELSE 0 END) AS 'rugby',
  ...
FROM users
LEFT JOIN pmainduction_user ON users.id         = pmainduction_user.user_id
LEFT JOIN pmainductions     ON pmainductions.id = pmainduction_user.pmainduction_id
GROUP BY users.id;

如果您为每个用户提供了未知数量的导入,并且您想要动态执行此操作,则可以执行以下操作:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(p.Name = ''',
      p.Name, ''', 1, 0)) AS ', '''',   p.Name , '''')
  ) INTO @sql
FROM users u
LEFT JOIN user_inductions up ON u.id = up.user_id
LEFT JOIN inductions      p ON p.id = up.induction_id;

SET @sql = CONCAT('SELECT u.name AS user,' ,
                  @sql, ' FROM users u ',
                  ' LEFT JOIN user_inductions up ',
                  ' ON u.id = up.user_id',
                  ' LEFT JOIN inductions      p     ',
                  ' ON p.id = up.induction_id ',
                  ' GROUP BY u.id');
SELECT @sql;

prepare stmt 
FROM @sql;

execute stmt;

SQL Fiddle Demo

这会给你类似的东西:

| USER | TENNIS | CRICKET | RUGBY | SQUASH | FOOTBALL | TABLE TENNIS | TWO WORDS |
----------------------------------------------------------------------------------
|  bob |      1 |       1 |     1 |      1 |        1 |            0 |         0 |
| paul |      1 |       1 |     1 |      1 |        1 |            1 |         1 |