Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL如何透视数据以显示数据库中属于多个组的用户_Mysql_Pivot Table - Fatal编程技术网

MySQL如何透视数据以显示数据库中属于多个组的用户

MySQL如何透视数据以显示数据库中属于多个组的用户,mysql,pivot-table,Mysql,Pivot Table,我正在尝试为Modx编写一个导出脚本,该脚本将显示属于多个组的成员,我已经做到了这一点: select u.id, u.username, u.primary_group, mgn.name, CASE WHEN mgn.name = 'Administrator' THEN 'TRUE' ELSE 'FALSE' END AS `Administrator`, CASE WHEN mgn.name = 'Members' THEN 'TRUE' ELSE 'FALSE' END

我正在尝试为Modx编写一个导出脚本,该脚本将显示属于多个组的成员,我已经做到了这一点:

select u.id, u.username, u.primary_group, mgn.name,
    CASE WHEN mgn.name = 'Administrator' THEN 'TRUE' ELSE 'FALSE' END AS `Administrator`,
    CASE WHEN mgn.name = 'Members' THEN 'TRUE' ELSE 'FALSE' END AS `Members`,
    CASE WHEN mgn.name = 'Privileged Members' THEN 'TRUE' ELSE 'FALSE' END AS `Privileged Members`
from modx_users u
left join modx_member_groups mg on mg.member = u.id
left join modx_membergroup_names mgn on mgn.id = mg.user_group
#where u.username = 'administrator'
#group by u.username
limit 10000;
在查询中,它确实会将用户组成员身份显示为true或false,但如果用户属于多个组,则查询将返回3行。如果我取消对GROUPBY条件的注释,则如果成员属于多个组,则对于多个组,它将不会显示TRUE

它也非常慢。在大约10000个用户的数据库上运行10++秒


如何解决此问题,在一行上显示每个用户想要导出到CSV并显示多个组成员身份

要提高性能,可能需要向表中添加适当的索引。此查询应满足您的要求:

SELECT
  id, username, primary_group,
  CASE MAX(`Administrator`) WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS `Administrator`,
  CASE MAX(`Members`) WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS `Members`,
  CASE MAX(`Privileged Members`) WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS `Privileged Members`
FROM (
  SELECT u.id, u.username, u.primary_group,
    CASE WHEN mgn.name = 'Administrator' THEN 1 ELSE 0 END AS `Administrator`,
    CASE WHEN mgn.name = 'Members' THEN 1 ELSE 0 END AS `Members`,
    CASE WHEN mgn.name = 'Privileged Members' THEN 1 ELSE 0 END AS `Privileged Members`
  FROM modx_users u
  LEFT JOIN modx_member_groups mg on mg.member = u.id
  LEFT JOIN modx_membergroup_names mgn on mgn.id = mg.user_group
) z
GROUP BY id, username, primary_group

这是一个删除额外连接的版本,假设101、102和103分别是管理员、成员和特权成员的ID值,并从分组中删除用户名和主组。在所有条件相同的情况下,它的性能应该比原来的稍好一些:

SELECT
  uuu.id,
  uuu.username,
  uuu.primary_group,
  `Administrator`,
  `Members`,
  `Privileged Members`
FROM
  modx_users uuu
  LEFT JOIN
  (
    SELECT
      z.id,
      CASE MAX(`Administrator`) WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS `Administrator`,
      CASE MAX(`Members`) WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS `Members`,
      CASE MAX(`Privileged Members`) WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS `Privileged Members`
    FROM
    (
      SELECT u.id,
        CASE WHEN mg.user_group = 101 THEN 1 ELSE 0 END AS `Administrator`,
        CASE WHEN mg.user_group = 102 THEN 1 ELSE 0 END AS `Members`,
        CASE WHEN mg.user_group = 103 THEN 1 ELSE 0 END AS `Privileged Members`
      FROM modx_users u
      LEFT JOIN modx_member_groups mg on mg.member = u.id
    ) z
    GROUP BY z.id
  ) zz on uuu.id=zz.id

您的表上有哪些索引?两个表都有ID主键,成员组有一个角色和等级字段索引,我不需要membergroup_名称有“父”和“等级”索引,对我也没有用处。请提供SHOW CREATE TABLE。如果您有多个成员资格,是否使用SET?还是多行?是的,谢谢。还是慢。我可以为mg.user\u组交换mgn.name,并与mgn表中的ID匹配,mg.user\u group=1,但没有速度改进,因为mg.user\u组列没有索引。我当然可以添加索引,但不确定将来的更新是否会删除它?通过使用mg.user\u group而不是mgn.name,似乎可以完全消除与modx\u membergroup\u names表的连接。如果是这样的话,这将有助于提高绩效。是的-是的,我们可以做到。它确实有效,但对速度没有明显的影响——在一个拥有大约10000个用户的数据库中,仍然需要10秒左右。在mg.member、mg.user_组上建立一个复合索引可能会有很大帮助。将username和primary_组从分组中去掉也可能有点帮助,尽管我可能希望MySQL能够优化它本身。添加索引会使它在系统间和升级过程中的可移植性大大降低。刚刚对不同服务器的实时数据进行了测试,结果花了140秒才恢复。我想我需要另一个解决方案。不知道我是否可以选择组成员ID作为数组,并在转换为CSV时在php中处理它。。。。