MySQL如何透视数据以显示数据库中属于多个组的用户
我正在尝试为Modx编写一个导出脚本,该脚本将显示属于多个组的成员,我已经做到了这一点: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
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中处理它。。。。