Ik probeer om in 1 query ALLE gegevens en ook de JUISTE te hebben.
Ik moet ALLE logins hebben maar ook ALLE gallerijen. Deze worden gekoppeld via hun resectievelijke id.
Als ik geen 'on' koppeling gebruik krijg ik gewoon het product van de records van alle tabellen. Wat logisch is. Maar op deze maniet weet ik niet wat het toegangsniveau is van de gallerij. Op de ene gallerij kan je andere rechten hebben dan op de andere. Als ik wel een 'on' koppeling gebruik dan ontbreek ik gallerijen welke nog geen rechten gekregen hebben.
In het verleden gebruikte ik 3 queries en liet ik php het werk doen maar ik denk dat het wel moet kunnen via sql.
Jan
select
l.id lid,
l.login,
l.schermnaam,
g.titel,
g.id gallerijid,
lg.niveau
from
logins l
join
gallerijen g
#on g.id=lg.gallerij
join
logins2gallerij lg
#on l.id=lg.login
?Onbekende gebruiker
20-11-2021 13:05
Wat je nodig hebt bij een meer-op-meer-relatie (M:M) is een koppeltabel, waarin de ID's staan naar de andere twee tabellen. Dus de tabel `logins2gallerij` moet een kolom hebben die wijst naar `logins`.`id` én een andere kolom die wijst naar `gallerijen`.`gallerij` (aannemende dat dit de kolom is met de primaire sleutel).
De naamgeving is een beetje verwarrend, en ik kan het gebruik van Foreign Keys aanbevelen, dus ik doe het even zo.
-- betere naamgeving
ALTER TABLE `logins` RENAME TO `login`;
ALTER TABLE `login` ALTER COLUMN `schermnaam` RENAME TO `naam`;
ALTER TABLE `gallerijen` RENAME TO `galerij`;
ALTER TABLE `galerij` ALTER COLUMN `gallerij` RENAME TO `id`; -- aanname dat dit de PK is
ALTER TABLE `galerij` ALTER COLUMN `schermnaam` RENAME TO `naam`;
ALTER TABLE `logins2gallerij` RENAME TO `login_galerij`;
ALTER TABLE `login_galerij` ALTER COLUMN `id` RENAME TO `login_fk`;
ALTER TABLE `login_galerij` ALTER COLUMN `<naam van kolom met id's van galerijen` RENAME TO `galerij_fk`;
-- database moet garanties geven op consistentie van gegevens
ALTER TABLE `login_galerij` ADD CONSTRAINT `login_galerij_galerij_fk_fkey` FOREIGN KEY (`galerij_fk`)
REFERENCES `galerij` (`id`) ON UPDATE CASCADE ON DELETE RESTRICT;
ALTER TABLE `login_galerij` ADD CONSTRAINT `login_galerij_login_fk_fkey` FOREIGN KEY (`login_fk`)
REFERENCES `login` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;
-- query voor het ophalen van alle gegevens zoals gevraagd
SELECT
`login`.`id` AS `login_id`,
`login`.`login`,
`login`.`naam` AS `gebruiker`,
`galerij`.`naam` AS `galerij`,
`galerij`.`id` AS `galerij_id`,
`login_galerij`.`niveau`
FROM `login_galerij`
INNER JOIN `galerij`
ON `login_galerij`.`galerij_fk` = `galerij`.`id`
INNER JOIN `login`
ON `login_galerij`.`login_fk` = `login`.`id`
-- ORDER BY `login`.`naam`, `galerij`.`naam`
Dit is hoe ik het zou doen, maar het kan ook anders. Omdat het INNER JOINs zijn kan je ook schrijven:
[..]
FROM `login_galerij`, `galerij`, `login`
WHERE `login_galerij`.`galerij_fk` = `galerij`.`id`
AND `login_galerij`.`login_fk` = `login`.`id`
Maar ik heb het gevonden met een cross join en dan een left join
select
l.id lid,
l.login,
l.schermnaam,
g.titel,
g.id gallerijid,
lg.niveau
from
logins l
cross join
gallerijen g
left join
logins2gallerij lg
on l.id=lg.login and
g.id=lg.gallerij
order by
l.schermnaam,
g.id
Bedankt
?Onbekende gebruiker
21-11-2021 12:38
gewijzigd op 21-11-2021 12:39
Op die manier krijg kun je te veel rijen terugkrijgen en moet je in PHP gegevens gaan filteren wanneer kolom `niveau` NULL-waarden bevat.
En het is inefficiënt om een CROSS JOIN te doen met een carthesisch product als resultaat, om daarop weer een LEFT JOIN te doen op een tabel waarin alle relaties al staan.
Het uitgangspunt voor het FROM statement moet zijn de tabel `logins2gallerij` (sic) waarna je met een LEFT JOIN naar `logins` en met een LEFT JOIN naar `gallerij` (sic) koppelt. Niet alleen is dat efficiënter, maar ook simpeler om te lezen.
Overigens heb je zonder FK-relaties met een LEFT JOIN nog steeds een mogelijkheid op lege rijen met NULL-waarden in kolommen, die je dan weer moet filteren in PHP. Dat kan je voorkomen met FK-relaties en/of gebruik van INNER JOIN.
Voor het overige moet je natuurlijk zelf weten welke naamgeving je aanhoudt. PHP staat er om bekend als een omgeving waarin iedereen fijn zelf kan ontdekken.
Juist wat null betreft. Echter voor de rest heb ik exact het aantal records welke ik nodig heb. Galerijen maal logins. Waarbij null gelijk staat als nog niet gedefinieerd en anders de juiste en wel al ingestelde waarde.
Het gaat hier over tonen en aanpassen van de rechten dus moet ik ze toch allemaal hebben.
Jan
?Onbekende gebruiker
22-11-2021 08:46
Excuus, dan heb ik je verkeerd begrepen.
Als je alles tegelijk wilt tonen dan is jouw aanpak inderdaad de beste.
Bepalend voor de aanpak is het aantal rechten en gebruikers.
Bij weinig gebruikers en rechten kan je alles tegelijk op het scherm tonen zonder dat prestaties daaronder veel te lijden hebben.
Bij complexere applicaties met veel rechten, rollen en gebruikers is het niet te doen om alles op 1 scherm te hebben, en is er veel te zeggen voor de andere aanpak.
Je kan (als alles goed is) enkel testen op "Doe even wat jullie willen".
Gelieve login en wachtwoord niet te wijzigen of te herstellen naar huidig indien je het toch test. Anders kan er niemand meer op deze login.
opmerkingen
Deze gallerij blijft slechts een paar weken openlijk toegankelijk.
Laad geen politieke, racistische, pornografische illegale of copyright foto's op.