2009-06-11 9 views
1

MySqlのサブクエリに問題があります。私はユーザーグループを含むテーブルを持っています。 (IdがINT、名前VARCHAR、ある他のすべてのTINYINT(1)(ブーリアン)MySqlの相関サブクエリ - まず外部クエリを評価する方法は?

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

私の目標のことができるようにすることである:カラムは、ID、名前、および各行を説明するコメントを有する特性でありますユーザグループのプロパティ(ログイン、ポスト及び上記管理)と(それぞれ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 is al方法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

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)'; 

はこの作業を取得するにはどのような方法があります)は常に0ですか?つまり、最初に外側のステートメントを評価するのですか?

-

任意の助けてくれてありがとうたくさん!

/ビクター

答えて

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; 

私は仮定しているこれらは、あなたのテーブルが持つ唯一の3つのプロパティがあります。各ユーザーグループに対して拡張可能な権限セットが必要な場合は、それぞれのユーザー特権ペアごとに1つの行を持つ別々のテーブルに格納することをお勧めします。

また、表の主キーとしてNameを使用することをお勧めします。より直感的で、おそらく一意である必要があります。

+0

ありがとう、しかし、行を数えることは実際には問題ではありません。問題は、description_schema(説明や "pretty name"として使用されています)からコメントを取得する必要があります。カウントが追加されました。とにかくありがとう! – Victor

0

これは、実際にリレーショナルデータベースを使用する方法ではありません。あなたはは、おそらくそれは

...

PREPARE stmt FROM 'SELECT COUNT(*) FROM db.usergroups WHERE ' + col_name + '=1'; 
-- Execute statement etc... 
をプリペアドステートメントを使用して行うことができます。しかし、動的にこれを行うための現実的な方法は、行に列を区切る(すなわち、別のテーブルには、 db.permissiontypesやその他もろもろと呼ばれてきた、そして db.usergroupsでそれに参加することです。)

+0

"それは本当に方法ではありません..." - そうです...私は通常、これに同意します(そしてあなたが示唆するように余分なテーブルを作成します)。特に、列名以外の情報を追加する可能性があります列のコメント。しかし、この場合(名前と説明がすべて必要なので)、それらを列として配置すると、1回の結合を省略して通常の操作を少し高速化できることを意味します。 "より良い"方法では、 "usertable JOIN usergroups JOIN usergroupproperties"を実行する必要があります。 "usertable JOIN usergroups"で十分です。 そして..上司がそれを求めました! ;-) – Victor

+0

Hmmm ...構造が石に置き換えられていても変更できないと主張することはできませんが、パフォーマンスが向上する限り、リレーショナルデータベースではパフォーマンスが向上します。非リレーショナル方法。とにかくこの場合ではありません。内部最適化のおかげで、別のテーブルを持つことは間違いなくダイナミックSQLより高速になります。 – Blixt

+0

ええと...それは私には本当に奇妙に聞こえる...本当ですか?私はもちろん、私たちがここで議論しているクエリの種類はかなり遅いですが、通常は(管理ページに基本的にアクセスしないと)必要な情報はuser + group + groupのプロパティです(つまり、各テーブルの行)。それ以外の場合は、結果を3つのテーブルから結合する必要があります(それぞれから1つの行を取得します)。確かに、違いは大きくないかもしれませんが、3つのテーブルではより速くなりません。 また、後者の場合、パフォーマンス上の利点を得るために外部キーを明示的に指定する必要がありますか? – Victor

関連する問題