Avatar billede shubijam Nybegynder
06. april 2005 - 13:34 Der er 12 kommentarer og
1 løsning

Mange-til-mange-relationer, igen igen.

Hej Eksperter

Jeg har orienteret mig lidt i de tidligere indlæg ang. mange-til-mange-relationer, men synes ikke, jeg kan finde et svar.

Jeg anvender følgende tabeller:
- varer
- kategorier
- varer_kategorier (indeholder varer_ref og kategorier_ref)

En vare kan indgå i mange kategorier, og en kategori kan have mange varer.

I den webshop, der er tale om, skal man kunne søge på et ubestemt antal kategorier, som vinges af. Det kunne fx være "Puder", "Jul" og "Rød". Denne søgning skulle gerne vise alle de varer, som er tilknyttet minimum alle disse tre kategorier - altså røde julepuder.

PROBLEM:
Jeg har problemer med at foretage denne søgning, da jeg kun ved, hvordan jeg finder alle de varer, som er tilknyttet én af kategorierne.
Dette kunne fx gøres ved

SELECT * FROM varer_kategorier WHERE Kategorier_ref IN ('Puder','Jul', 'Rød')

Her anvender jeg naturligvis kategoriernes Id'er i stedet for navnene. Denne søgning vil give alt for mange resultater, idet en vare, som kun er tilknyttet "Jul" også vil komme med.

Håber, spørgsmålet er til at tyde - har i et bud?
Avatar billede barklund Nybegynder
06. april 2005 - 13:38 #1
Hm, man kunne jo joine med varer_kategorier tre gange - en gang for hver kategori - men det kan næppe være den smarteste metode. Hvis ingen kommer med et bedre forslag, skal jeg da gerne stykke et sql-script sammen til dig.
Avatar billede shubijam Nybegynder
06. april 2005 - 13:40 #2
Jeg er i tvivl om, hvordan jeg laver disse joins. Desuden kunne det lige så vel være, at der blev søgt på fem kategorier - men det kunne man vel bare genere dynamisk. Du må meget gerne skrive, hvordan jeg kan joine varer_kategorier tre gange - så kan jeg se, om jeg kan skræddersy det.
Avatar billede barklund Nybegynder
06. april 2005 - 13:59 #3
Altså, du kan lave en


SELECT v.* FROM varer AS v
INNER JOIN varer_kategorier AS v1 ON v.id = v1.varer_ref AND v1.kategorier_ref = 'jul'
INNER JOIN varer_kategorier AS v2 ON v.id = v2.varer_ref AND v2.kategorier_ref = 'rød'
INNER JOIN varer_kategorier AS v3 ON v.id = v3.varer_ref AND v3.kategorier_ref = 'puder'

Men optimalt ser det jo ikke ud :)

Dog er det vel også sjældent, at man laver en AND-søgning på tværs af kategorier - eller hvad? :)

--
Morten Barklund
Avatar billede shubijam Nybegynder
06. april 2005 - 14:46 #4
Hej igen - mange tak for de hurtige svar.

Jeg kan ikke umiddelbart anvende eksemplet, da jeg ikke helt forstår v.* og de følgende v'er. Skulle dette give mig et dataset over de varer, som indgår i de tre kategorier?
Avatar billede barklund Nybegynder
06. april 2005 - 15:32 #5
Ja, v er bare et kort navn for varer-tabellen (som vist i varer AS v) og v1, v2 og v3 er tre forskellige instanser af varer_kategorier-tabellerne.

Så du skal bare rette originalnavnene varer og varer_kategorier samt attributnavnene - men beholde de korte navne, altså v, v1, v2 og v3.
Avatar billede shubijam Nybegynder
06. april 2005 - 16:35 #6
Hej Morten

Du har været til stor hjælp. Jeg har nu fået det til at virke, så jeg er glad.
Er det ikke noget med, at du skal give et "Svar" før jeg kan give dig point.
Avatar billede barklund Nybegynder
06. april 2005 - 16:52 #7
Helt korrekt.

Jeg tror ikke, der er en nemmere mulighed, men det er muligt, at nogen andre kommer og siger, at jeg er en stor fed løgner - og så tager jeg det så i mig.
Avatar billede barklund Nybegynder
06. april 2005 - 17:07 #8
Tark for points anyways :)
Avatar billede shubijam Nybegynder
06. april 2005 - 17:10 #9
Velbekomme - det virker i hvert fald rigtig godt...
Avatar billede bromer Nybegynder
06. april 2005 - 17:14 #10
Bare lige for at være lidt nasty så vil jeg lige nævne at man kan lave en normal "OR" søgning, GROUP BY varenr, og så HAVING COUNT(1) = <antal_af_kategorier_man_søger_i>, men det er mega nasty...
Avatar billede barklund Nybegynder
06. april 2005 - 17:18 #11
Det må blive noget med:

SELECT v.* FROM varer AS v
INNER JOIN varer_kategorier AS v1 ON v.id = v1.varer_ref AND v1.kategorier_ref IN ('jul','rød','puder') GROUP BY v1.id HAVING COUNT(DISTINCT v1.kategorier_ref)) = 3

Men jeg tvivler på, at det performer meget bedre :D
Avatar billede shubijam Nybegynder
06. april 2005 - 17:22 #12
OK - tak til jer begge to. Jeg tror bare, jeg bibeholder den oprindelige løsning. Men - alle tiders!
Avatar billede bromer Nybegynder
06. april 2005 - 17:24 #13
shubijam: Gide du ikke køre en explain på begge og poste resultatet her?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester