SQL: relaterade tabeller, join, distinct och en vilja att göra något ovanligt

Tråden skapades och har fått 6 svar. Det senaste inlägget skrevs .
1

Ok, tolka inte ur några konstigheter ur rubriken - allt handlar om sql.

Fakta: Jag har en databas som består av tre tabeller. I den första finns data om olika filer. Den andra är en "mellantabell" för relationer och den tredje är en tabell med olika kategorier. Tanken är att varje fil skall kunna ha ett flertal kategorier relaterade till sig via mellantabellen.

Problem: När jag utför en sökning vill jag även hämta ut alla kategorier som tillhör en bild. Med mina joins lyckas jag lösa det på två olika och otillfredsställande sätt: antingen utelämnar jag kategorierna elternativt hämtar jag in dem men i så fall kommer jag i min resultattabell få skilda rader för samma fil men med enda skillnaden kategorinamnet. Alla andra data samma.

Önskan: att på något sätt hämta in kategorierna (jag joinar in dem redan idag men få separata rader i resultattabellen för varje särskild kategori men samma fil) till en fil, samtliga, kommaseparerade eller liknande, till fältet kategori i resultattabellen.

Skall se om jag kan fixa några utdrag ur mySQL för det här blev rörigt märkte jag...

Ex på filer-tabellen:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">+-----+-------------+
| id | filnamn |
+-----+-------------+
| 168 | v008-12.jpg |
+-----+-------------+</pre>

Ex på relatera-tabellen:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">+-----+--------+------+
| id | fromid | toid |
+-----+--------+------+
| 4 | 1 | 2 |
| 257 | 2 | 2 |
+-----+--------+------+
</pre>

Ex på kategori-tabellen:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">+----+--------------+
| id | kategorinamn |
+----+--------------+
| 5 | blandat |
| 6 | natur |
+----+--------------+</pre>

Följande sql-sats:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">SELECT DISTINCT
bilder.id, bilder.filnamn, kategorier.kategorinamn
FROM
bilder
LEFT JOIN
relateratabell
ON
bilder.id = relateratabell.fromid
LEFT JOIN
kategorier
ON
relateratabell.toid = kategorier.id
WHERE
(relateratabell.fromid IS NULL OR relateratabell.fromid IS NOT NULL)
AND
bilder.stickord LIKE ´%basta%´
ORDER BY
filnamn; </pre>

ger följande resultat:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">+---+-----------+--------------------------+
| id | filnamn | kategorinamn |
+---+-----------+--------------------------+
| 166| v007-86.jpg | demonstrationer |
| 166| v007-86.jpg | människor |
| 167| v008-03.jpg | demonstrationer |
| 167| v008-03.jpg | människor |
+---+-----------+--------------------------+</pre>

Det är det här som är problemet. Jag vill inte ha 2 rader för fil med id 166 eller 167. Jag vill snarare få det här resultatet:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">+---+-----------+--------------------------+
| id | filnamn | kategorinamn |
+---+-----------+--------------------------+
| 166| v007-86.jpg | demonstrationer, människor |
| 167| v008-03.jpg | demonstrationer, människor |
+---+-----------+--------------------------+</pre>

Gjorde detta det lättare eller svårare att förstå?

(Ber om ursäkt för att asci-grafiken laggar ur...)

  • Medlem
  • Stockholm
  • 2003-03-05 14:29

Det här är kanske inte det svar du vill ha, men du kan ju alltid loopa igenom fillistan och kolla vilka kategorier varje bild tillhör med en egen query, men då blir det förstås många queries om fillistan är lång. Kanske blir för tungt?

Ett annat alternativ är ju att eliminera dubletterna "själv" när du får tillbaka svaret, men då funkar ju inte riktigt LIMIT om du behöver använda det...

Jag har haft samma fundering själv, men jag valde faktiskt att avstå från att kunna visa det som motsvarar dina kategorier i listningen av det som motsvarar dina filer. Du kanske kan nöja dig med att lista kategorierna när användaren går in på en enskild fil?

Detta har malt i mitt huvud också några år nu. Inte i det här sammanhanget men i andra. I och med att vi snackar _jättemånga_ poster i databasen och jag hämtar ut dem med LIMIT vill jag ha det till att funka direkt när mySQL returnerar resultatet...

  • Medlem
  • Stockholm
  • 2003-03-05 14:53

Har funderat lite till... Såhär kanske man kan göra?

Först en fråga för att ta fram just de filer du ska ha:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">SELECT DISTINCT
ID
FROM
filer
<dina joins här>
WHERE
xxxxxxx
LIMIT
X,X</pre>

Sen en fråga som tar fram rubbet för just de filerna - med eller utan dubletter:

Citat:

kod:<pre style="font-size:x-small; font-family: monospace;">SELECT
<alla fält du vill ha med>
FROM
filer
<dina joins här>
WHERE
filer.id = ´<fil 1>´
OR
filer.id = ´<fil 2>´
<osv></pre>

Du skapar alltså en WHERE-sats utifrån resultatet från den första frågan.
Sen måste du förstås kolla efter dubletter i resultatet.

Har inte testat nåt sånt själv, men det borde väl funka.

- - - -
(La för ordningens skull till DISTINCT i första frågan.)

[ 05. mars 2003, 18:13: Meddelandet ändrat av: HL ]

Om jag hänger med i svängarna nu menar du att jag meddelst php eller liknande middleware skall hämta ut kategorierna i en andra mysql-query och pussla ihop det på så sätt?

Det är antagligen den bästa lösningen om det inte går att göra det redan vid den första selecten, men jag hoppas fortfarande på att någon själ vet hur man gör...

  • Medlem
  • Stockholm
  • 2003-03-05 18:15
Citat:

citera:Skapades ursprungligen av: scooterbabe:
Om jag hänger med i svängarna nu menar du att jag meddelst php eller liknande middleware skall hämta ut kategorierna i en andra mysql-query och pussla ihop det på så sätt?

Exakt. Och jag håller med, om någon har en lösning på att göra allt på en gång så vore det ju super.

1
Bevaka tråden