1

我在 MySql 中遇到子查询问题。我有一个包含用户组的表。列是 id、name 和带有描述每一行的注释的属性:(Id 是 INT,Name VARCHAR,所有其他 TINYINT(1)(即布尔值)

ID   |   Name   |   login   |   post   |   manage
 1     user           1           0           0
 2     poster         1           1           0
 3     admin          1           1           1

我的目标是能够列出用户组属性(上面的登录、发布和管理)以及具有每个属性的用户组数量(分别为 3、2 和 1)。

此查询有效(但显然每次都计算登录列):

SELECT @colname:=cols.column_name,cols.column_comment,
  (SELECT COUNT(*) FROM db.usergroups WHERE login=1) AS num_users
FROM information_schema.columns AS cols 
WHERE TABLE_SCHEMA='db' AND TABLE_NAME='usergroups' AND column_type='tinyint(1)';

这不起作用(num_users 始终为 0)

SELECT @colname:=cols.column_name,cols.column_comment,
  (SELECT COUNT(*) FROM db.usergroups WHERE cols.column_name=1) AS num_users
FROM information_schema.columns AS cols 
WHERE TABLE_SCHEMA='db' AND TABLE_NAME='usergroups' AND column_type='tinyint(1)';

这两者都没有(num_users 始终为 0)

SELECT @colname:=cols.column_name,cols.column_comment,
  (SELECT COUNT(*) FROM db.usergroups WHERE @colname=1) AS num_users
FROM information_schema.columns AS cols 
WHERE TABLE_SCHEMA='db' AND TABLE_NAME='usergroups' AND column_type='tinyint(1)';

有什么办法可以让它工作吗?那就是-首先评估外部语句?

-

非常感谢您的帮助!

/胜利者

4

2 回答 2

1

如果我正确理解您的问题,我认为这可能会满足您的需求:

select
  sum(login) as Num_Login_Groups,
  sum(post) as Num_Post_Groups,
  sum(manage) as Num_Manage_Groups
from db.usergroups;

或者,如果您确实需要“登录”、“发布”和“管理”与具有该权限的组数出现在同一行,您可以这样做:

select 'login' as Property, sum(login) as Count from db.usergroups
union
select 'post' as Property, sum(post) as Count from db.usergroups
union
select 'manage' as Property, sum(manage) as Count from db.usergroups;

我假设这些是您的表将拥有的仅有的三个属性。如果您想要为每个用户组提供一组可扩展的权限,我建议将它们存储在一个单独的表中,每个适用的用户权限对对应一行。

您也可以考虑将Name其用作表的主键,因为它更直观,并且可能无论如何都需要是唯一的。

于 2009-06-11T12:35:16.230 回答
0

这真的不是使用关系数据库的方式。您可能可以使用准备好的语句来做到这一点......

PREPARE stmt FROM 'SELECT COUNT(*) FROM db.usergroups WHERE ' + col_name + '=1';
-- Execute statement etc...

但是动态执行此操作的真正方法是将列分成行(即有另一个表称为db.permissiontypes或诸如此类,然后将其与db.usergroups.)

于 2009-06-11T12:39:43.193 回答