Hallo Werner,
Die Gruppen sind als nested set abgelegt.
┌──────────────────────────────┐ ┌───────────────┐ ┌──────────────────┐
│ table.groups │ │ table.user │ │ table.corre_g_u │
├─────────┬──────┬──────┬──────┤ ├────────┬──────┤ ├─────────┬────────┤
│ groupId │ name │ lKey │ rKey │ │ userId │ name │ │ groupId │ userId │
├─────────┼──────┼──────┼──────┤ ├────────┼──────┤ ├─────────┼────────┤
│ 1 │ foo │ 1 │ 10 │ │ 1 │ Uwe │ │ 1 │ 1 │
├─────────┼──────┼──────┼──────┤ ├────────┼──────┤ ├─────────┼────────┤
│ 2 │ bar │ 2 │ 5 │ │ 2 │ Klaus│ │ 1 │ 2 │
├─────────┼──────┼──────┼──────┤ ├────────┼──────┤ ├─────────┼────────┤
│ 3 │ bla │ 3 │ 4 │ │ 3 │ Gabi │ │ 2 │ 3 │
├─────────┼──────┼──────┼──────┤ ├────────┼──────┤ ├─────────┼────────┤
│ 4 │ blub │ 6 │ 7 │ │ 4 │ Inge │ │ 3 │ 1 │
├─────────┼──────┼──────┼──────┤ ├────────┼──────┤ ├─────────┼────────┤
│ 5 │ beta │ 8 │ 9 │ │ 5 │ Gerd │ │ 3 │ 4 │
└─────────┴──────┴──────┴──────┘ ├────────┼──────┤ ├─────────┼────────┤
│ 6 │ Sepp │ │ 4 │ 5 │
└────────┴──────┘ ├─────────┼────────┤
│ 5 │ 6 │
└─────────┴────────┘
ehrlich gesagt verstehe ich nicht im geringsten, was diese Aussage
Dann suche ich von den Gruppen alle Benutzer die in Untergruppen sind ABER NICHT in
übergeordneten Gruppen. Und daran scheitere ich.
mit diesen Beispielen
- Uwe sieht alle Benutzer ausser Klaus und sich selbst
- Klaus sieht alle Benutzer ausser Uwe und sich selbst
- Gabi sieht nur Inge
- Inge sieht gar nichts weil ihre Gruppe keinen Zugriff auf das Modul hat
- Gerd sieht niemanden weil seine Gruppe keine Untergruppe hat
- Sepp sieht aus dem selben Grund auch niemanden
zu tun hat und
Im Idealfall hätte ich gern nur eine Abfrage und keine doppelten Datensätze für den zweiten
Teil damit ich SQL_CALC_FOUND_ROWS noch verwenden kann. Das Ergebnis der Abfrage sollte
auch nach den Gruppennamen sortierbar sein.
welches Ergebnis Du gerne hättest.
Aber ein paar Tipps:
1. Reine Untergruppen sind in Nested Sets dadurch gekennzeichnet,
dass der Wert des rKey um genau 1 größer ist als der rKey:
-- Alle Blätter, d.h. reine Untergruppen
SELECT
groupId
FROM
groups
WHERE
rKey = lKey + 1;
Ergebnis:
groupId
-------
3
4
5
2. Somit ergibt sich für übergeordnete Gruppen, dass der rKey nicht
um 1 größer sein darf als der rKey:
-- Alle übergeordneten Gruppen
SELECT
groupId
FROM
groups
WHERE
rKey != lKey + 1;
Ergebnis:
groupId
-------
1
2
3. Benutzer, die in Untergruppen sind (aber auch in übergeordneten
Gruppen sein können), findest Du über
SELECT -- Gib mir
userId -- die userIds
FROM -- aus der Liste
groups_user -- der Gruppen-User-Zuordnung
WHERE -- deren
groupId -- GruppenId
IN ( -- in der
SELECT -- Liste der Blätter enthalten sind
groupId
FROM
groups
WHERE
rKey = lKey + 1
);
Ergebnis:
userId
-------
1
4
5
6
4. Analog findet man die Benutzer, die in übergeordneten Gruppen sind mit
SELECT
userId
FROM
groups_user
WHERE
groupId
IN (
SELECT
groupId
FROM
groups
WHERE
rKey != lKey + 1
);
Ergebnis
userId
-------
1
2
3
und somit findet man Benutzer, die nur in Untergruppen sind, mit der Kombination von 3 und 4:
Gib mir alle Benutzer, die in 3 sind, aber nicht in 4 (es muss Benutzer 1 rausfallen):
SELECT -- Alle Benutzer
userId
FROM
groups_user
WHERE
groupId -- aus Untergruppen
IN (
SELECT
groupId
FROM
groups
WHERE
rKey = lKey + 1
)
AND -- die nicht
userId NOT IN ( -- in Übergruppen sind
SELECT
userId
FROM
groups_user
WHERE
groupId
IN (
SELECT
groupId
FROM
groups
WHERE
rKey != lKey + 1
)
);
Ergebnis:
userId
-------
4
5
6
Freundliche Grüße
Vinzenz