2009-06-11 6 views
1

Ich habe Probleme mit Unterabfragen in MySql. Ich habe eine Tabelle mit Benutzergruppen. Die Spalten sind ID, Name und die Eigenschaften mit einem Kommentar jede Zeile beschreibt: (Id ist INT, Namen VARCHAR, alle anderen TINYINT (1) (boolean, das ist)Korrelierte Unterabfragen in MySql - wie äußere Abfrage zuerst ausgewertet wird?

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

Mein Ziel ist es, in der Lage sein Liste der Benutzergruppen-Eigenschaften (Login, Post und verwalten oben) und die Anzahl der Benutzergruppen, die jede Eigenschaft (3, 2 bzw. 1)

Diese Abfrage funktioniert (aber natürlich zählt die Login-Spalte jedes Mal).

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

Dies funktioniert nicht (num_users ist al 0 Wege)

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

Dies weder (num_users ist immer 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)'; 

Gibt es eine Möglichkeit, dies zu erhalten zu arbeiten? Das ist - zuerst die äußere Aussage zu bewerten?

-

Vielen Dank für jede Hilfe!

/Victor

Antwort

1

Wenn ich Ihr Problem richtig verstehe, ich denke, das tun können, was Sie brauchen:

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

Alternativ, wenn Sie wirklich 'login' brauchen, 'Post' und 'verwalten' mit dem Privileg auf der gleichen Zeile wie die Anzahl der Gruppen angezeigt werden, können Sie dies tun:

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; 

ich gehe davon aus, das sind die drei Eigenschaften Tisch haben. Wenn Sie eine erweiterbare Gruppe von Berechtigungen für jede Benutzergruppe wünschen, würde ich vorschlagen, sie in einer separaten Tabelle mit einer Zeile für jede anwendbare Benutzerprivilegierungspaarung zu speichern.

Sie könnten auch in Betracht ziehen, Name als Primärschlüssel der Tabelle zu verwenden, da es intuitiver ist und wahrscheinlich sowieso eindeutig sein muss.

+0

Danke, aber das Zählen der Zeilen ist nicht wirklich das Problem - das Problem ist, dass ich (?) Den Kommentar von information_schema holen muss (was als Beschreibung oder "hübscher Name" verwendet wird) und in derselben Abfrage wollen die Zählung hinzugefügt. Danke trotzdem! – Victor

0

Das ist wirklich nicht die Art, eine relationale Datenbank zu verwenden. Sie könnte wahrscheinlich tut es mit Prepared Statements ...

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

Aber der eigentliche Weg, dies dynamisch zu tun ist, um die Spalten in Zeilen zu trennen (dh hat eine andere Tabelle db.permissiontypes oder Dingsbums genannt, verbindet es dann mit db.usergroups .)

+0

"Das ist wirklich nicht der Weg ..." - Nun ... Ich würde normalerweise dem zustimmen (und eine extra Tabelle machen, wie Sie vorschlagen), vor allem weil das Ihnen die Möglichkeit gibt, mehr Informationen als nur den Spaltennamen hinzuzufügen und Spaltenkommentar. ABER in diesem Fall (wie Name und Beschreibung ist alles was benötigt wird) setzen sie als Spalten bedeutet, dass ich einen Join weglassen und damit den normalen Betrieb ein wenig beschleunigen kann. Mit dem "besseren" Weg würde ich tun müssen "Usertable JOIN Usergroups JOIN usergroupproperties", jetzt "Usertable JOIN Usergroups" ist genug. Und .. Der Chef fragte danach! ;-) – Victor

+0

Hmmm ... Nun, ich kann nicht argumentieren, wenn die Struktur in Stein gemeißelt und unveränderbar ist, aber was die Performance betrifft, werden Sie in einer relationalen Datenbank keine bessere Leistung erzielen, wenn Sie sie nicht-relational lösen Weg. Nicht in diesem Fall sowieso. Eine andere Tabelle wird dank interner Optimierungen definitiv schneller sein als dynamisches SQL. – Blixt

+0

Hmm ... Das klingt wirklich seltsam für mich ... Bist du sicher? Ich Männer - natürlich die Art der Abfrage, die wir hier diskutieren, wird ziemlich langsam sein, aber normalerweise (wenn nicht auf die Admin-Seite im Grunde zugreifen) die einzige erforderliche Informationen ist Benutzer + Gruppe + Gruppeneigenschaften (was bedeutet, eine Verknüpfung von zwei Tabellen, eine Reihe von jeder Tabelle). Andernfalls muss das Ergebnis aus drei Tabellen zusammengesetzt werden (jeweils eine Zeile holen). Klar, der Unterschied ist vielleicht nicht groß, aber mit 3 Tabellen kann es nicht schneller sein, oder? Auch - im letzteren Fall - müssen Fremdschlüssel explizit angegeben werden, um den Leistungsvorteil zu erhalten? – Victor

Verwandte Themen