Datenbankabfrage über mehrere Tabellen
Pedro
- datenbank
Hallo zusammen
Stehe etwas an im moment. Habe mir schon div. SQL Statements angeschaut und im Query - Analizer und in PHP versucht umzusetzen. Ich krieg das jedoch nicht ganz so hin, wie ich möchte. Folgende DB struktur habe ich:
------------------ ------------------ ------------------
| users | | groups | | security |
------------------ ------------------ ------------------
| userName | | groupName | | userName |
| userPassword | ------------------ | groupName |
------------------ ------------------
In "users" sind alle Benutzer und Passwörter enthalten, in "groups" die Gruppen die es gibt und in "security" jeweils user und gruppenname falls der benutzer in einer gruppe ist.
Also z.B. in der security Tabelle:
pedro admin
pedro benutzer
etc.
ich möcht jetzt gerne folgende ausgabe generieren:
----------------------------------------------------------
| User | admin | benutzer | weitere gruppen |
----------------------------------------------------------
| Pedro | X | X | |
-----------------------------------------------------------
Also eine Art benutzerliste wo ersichtlich ist, welcher Benutzer in welcher Gruppe ist.
Ich hätte das jetzt einfach mit einer Tabelle gelöst und für jede gruppe eine Spalte gemacht, und dort eine 0 oder 1 gesetzt je nach zugehörigkeit. Ich habe mich jedoch belehren lassen, das man dies besser mit diesen 3 Tabellen macht, da, wenn eine weitere Gruppe dazu kommt nur die Tabelle "groups" erweitert werden muss, und an den PHP Scripten nichts verändert werden muss...
Nur stehe ich jetzt bei der Abfrage an ;-)
Besten Dank und Gruss
Pedro
Hi,
welchen datenbanktyp nutzt du?
mySQL (schwierig) oder Oracle (lösbar)
RingerSan
Hi
mysql
Wäre das dann mit der einen Tabelle, wie ich es als ansatz unten erwähnt habe die sinvollste lösung?
Gruss
Pedro
echo $begrueszung;
Wäre das dann mit der einen Tabelle, wie ich es als ansatz unten erwähnt habe die sinvollste lösung?
Der Drei-Tabellen-Ansatz ist schon der sinnvollste. Was du hast ist ja kein Datenbank-Problem sondern eher ein Darstellungsproblem.
Die Anzahl der Ergebnisspalten ist in MySQL durch deine SELECT-Klausel (*, Aufzählung der Feldnamen, berechnete Spalten, ... (noch mehr?)) festgelegt. Beim Hinzukommen oder Wegfallen von Gruppen müsstest du dir immer die SELECT-Klausel anpassen.
Du hast ja PHP, damit geht es beispielsweise so (du willst das Ergebnis doch sicher mit HTML darstellen):
Für die Ermittlung der Spalten der HTML-Tabelle wird einmalig die DB-Tabelle groups abgefragt. Das Ergebnis kommt ein ein Array, dass am Ende so aussieht:
$groups = array('groupName1', 'groupName2', ...);
Dann wird der Inhalt der DB-Tabelle security benötigt. Der kann unsortiert oder nach userName sortiert aus der DB gelesen weden.
Das folgende ist als Quelltext einfacher zu beschreiben als in Worten:
$users = array();
while ($row = mysql_fetch_assoc(...))
$users[$row['userName']][$row['groupName']] = 1; // [1]
Damit ist in $users eine Art Matrix entstanden. Das sieht dann so aus:
$users = array(
'userName1' => array('groupName1' => 1, 'groupName2' => 2),
'userName2' => array('groupName2' => 1),
'userName3' => array('groupName1' => 1),
...);
Zur Ausgabe kann man nun über $users foreach-en und darin jeweils über $groups foreach-en und testen, ob ein entsprechendes Element in $users gibt:
foreach($users as $name => $userGroups) {
...
echo $name;
...
foreach($groups as $groupName) {
...
echo isset($userGroups[$groupName])) ? 'X' : ''; // [2]
...
}
...
}
Anstelle der ... kommen die HTML-Tabs des Tabellenrumpfs. Der Kopf kann vorher ebenfalls mit einem foreach über $groups angezeigt werden.
Soweit so klar?
Alternativ könnte man:
[1] $users[$row['userName']][] = [$row['groupName']];
[2] echo in_array($groupName, $userGroups) ? 'X' : '';
verwenden. Das in_array() ist allerdings langsamer als die Abfrage der gesetzten Schlüssel, hab ich die Tage erst hier in einem anderen Thread gelesen.
Diese Lösung hat momentan allerdings einen kleinen Makel. User, die in keiner Gruppe sind, werden nicht angezeigt. Aber das kann man mit geringem Aufwand auch noch einfügen.
echo "$verabschiedung $name";
Damit ist in $users eine Art Matrix entstanden.
Hier wollte ich noch hinzuschreiben:
Für jede Gruppe in der ein User Mitglied ist, existiert nun ein Element in der verschachtelten Struktur $users.
Die sieht auf den ersten Blick sicher etwas komisch aus, da zwar für die Schnittpunkte User zu Gruppe zwar Felder existieren, für die Nicht-Schnittpunkte ist jedoch kein Leer-Element eingefügt, sondern einfach nichts da. :-)
Außerdem als Nachtrag noch etwas zum Nachdenken :-)
Was passiert, wenn dir bei deiner jetzigen Tabellenstruktur beispielsweise einfällt: Englisch ist "moderner", benennen wir doch einfach die Gruppe "Benutzer" um in "User" ?
Hallo dedlfix,
Außerdem als Nachtrag noch etwas zum Nachdenken :-)
Was passiert, wenn dir bei deiner jetzigen Tabellenstruktur beispielsweise einfällt: Englisch ist "moderner", benennen wir doch einfach die Gruppe "Benutzer" um in "User" ?
Kleiner Nachtrag an dich, denn der deutsche Begriff "Benutzer" fällt erst bei der Ausgabe. Die Tabellenstruktur an sich ist in Englisch.. ;-)
Bis dann!
Marc Reichelt || http://www.marcreichelt.de/
echo $begrueszung;
Kleiner Nachtrag an dich, denn der deutsche Begriff "Benutzer" fällt erst bei der Ausgabe. Die Tabellenstruktur an sich ist in Englisch.. ;-)
Dann muss ich wohl
Also z.B. in der security Tabelle:
pedro admin
pedro benutzer
etc.
falsch verstanden haben... oder?
echo "$verabschiedung $name";
Hallo dedlfix,
Kleiner Nachtrag an dich, denn der deutsche Begriff "Benutzer" fällt erst bei der Ausgabe. Die Tabellenstruktur an sich ist in Englisch.. ;-)
Dann muss ich wohl
Also z.B. in der security Tabelle:
pedro admin
pedro benutzer
etc.falsch verstanden haben... oder?
Sorry, da fass ich mir gleich mal selbst an die Nase. *grabsch*
Hatte das doch glatt übersehen und mich auf die "Tabellen" an sich konzentriert...
Kannst du mir verzeihen? ;-)
Bis dann!
Marc Reichelt || http://www.marcreichelt.de/
re
Kannst du mir verzeihen? ;-)
Aber selbstverständlich.
deflfix
Besten Dank für Deine Lösung.
Ich werde das morgen direkt ausprobieren. Genau das mit dem User der in keiner Gruppe ist benötige ich.
Bei welcher Variante werden die nicht angezeigt, bei der ersten oder zweiten? Und was für möglichkeiten gäbe es da?
Gruss
Pedro
echo $begrueszung;
Genau das mit dem User der in keiner Gruppe ist benötige ich.
Bei welcher Variante werden die nicht angezeigt, bei der ersten oder zweiten?
bei beiden
Und was für möglichkeiten gäbe es da?
Eine Idee wäre, $users nicht mit einem leeren Array zu initialisieren ($users = array();), sondern mit einer Abfrage aus der Tabelle users. Dabei müsste der Inhalt des Feldes userName als Key verwendet werden und ein leeres Array als Value. $users soll dann so aussehen:
$users = array(
'userName1' => array(),
'userName2' => array(),
...);
Das funktioniert mit beiden Varianten (isset/in_array) gleichermaßen.
Der Rest (while ... fetch (security) und die Ausgabe) bleibt gleich.
echo "$verabschiedung $name";
yo,
wenn du deine darstellung ein wenig modifizierst, sprich anstelle von weiteren spalten es in unterschiedlichen zeilen darstellst, dann sollte die abfrage einfach sein.
SELECT u.usersname, s.groupname
FROM users AS u LEFT JOIN security AS s ON (a.username = s.username)
Ilja