Avatar billede Slettet bruger
05. april 2006 - 23:07 Der er 13 kommentarer og
1 løsning

Left JOIN?

Min situation er som følger:

Jeg har to tabeller:

forum_threads:
+-----------+--------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO  | PRI | NULL    | auto_increment |
| header    | varchar(255) | NO  |    |        |                |
| besked    | text        | NO  |    |        |                |
| user      | int(11)      | NO  |    | 0      |                |
| time      | int(11)      | NO  |    | 0      |                |
| visninger | int(11)      | NO  |    | 0      |                |
| forum    | int(11)      | NO  |    | 0      |                |
+-----------+--------------+------+-----+---------+----------------+

forum_readposts:
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| user  | int(11) | NO  | PRI | 0      |      |
| traad | int(11) | NO  | PRI | 0      |      |
+-------+---------+------+-----+---------+-------+


forum_threads indeholder som navnet antyder trådene i mit forum. Når en bruger går ind og læser en tråd oprettes der en række i forum_readposts som angiver at brugeren har læst denne tråd.

Jeg ønsker nu at finde alle tråde hvor brugeren ikke har været inde og læse (altså hvor der ikke er noget post i forum_readposts med det bruger ID og den tråds id).

Jeg har prøvet med følgende select, men det virkede ikke:
SELECT header, traad FROM forum_threads LEFT JOIN forum_readposts ON forum_threads.id = forum_readposts.traad WHERE forum_readposts.user = 1;

Den ovenstående SQL burde efter min forståelse returnere alle posts, såvel ulæste som læste, men den returnerer kun de læste (som hvis jeg havde lavet en normal join).
Avatar billede arne_v Ekspert
06. april 2006 - 00:23 #1
SELECT header, traad FROM forum_threads LEFT JOIN forum_readposts ON forum_threads.id = forum_readposts.traad WHERE forum_readposts.traad IS NULL

måske
Avatar billede barklund Nybegynder
06. april 2006 - 10:57 #2
Du skal nok lige have brugerens id med i JOIN-betingelsen:

SELECT header, traad FROM forum_threads LEFT JOIN forum_readposts ON forum_threads.id = forum_readposts.traad AND forum_readposts.user = 1 WHERE forum_readposts.traad IS NULL

Med WHERE.-betingelsen (som arne_v også skrev) får du kun dem, han ikke har læst. Uden får du dem alle - både læste og ikke læste.
Avatar billede Slettet bruger
06. april 2006 - 12:19 #3
Barklund:
Jeg kom frem til nogenlunde det samme i nat, men  så kom jeg til at tænke på, at du jo ikke kan smide bruger ID med ind, for det er jo meningen at vi skal finde tråde hvor det IKKE ligger...

LEFT JOIN bruges til at finde posts i en tabel også selvom de ikke har noget modstykke i den anden tabel. I mit tilfælde vil jeg jo gerne finde dem som har et modstykke, jeg vil bare kun finde dem som ikke har noget GYLDIGT modstykke, dvs. dem hvor brugeren ikke har læst, altså hvor der ikke ligger noget post hvor traad = forum_threads.id og user = et givent bruger id.
Avatar billede Slettet bruger
06. april 2006 - 12:26 #4
Okay... Jeg har lige fået et syn :)

Her er en SQL sætning der virker:

SELECT header, traad FROM forum_threads LEFT JOIN (SELECT * FROM forum_readposts WHERE user = 1) forum_readposts ON forum_threads.id = forum_readposts.traad WHERE forum_readposts.traad IS NULL;
Avatar billede barklund Nybegynder
06. april 2006 - 12:48 #5
Virkede min query ikke? For jeg er med på, hvad du ville, men mener nu nok, at min query burde gøre det. Men ja, selvfølgelig kan det klares med en subselect :)
Avatar billede Slettet bruger
06. april 2006 - 13:57 #6
En left join viser NULL i alle felter hvis der ikke er noget modstykke i den anden tabel. Derfor kunne jeg ikke lave forum_readposts.user = 1, da den altid ville være NULL
Avatar billede barklund Nybegynder
06. april 2006 - 14:06 #7
Men det har jeg jo heller ikke lavet i min query? Jeg har jo netop flyttet WHERE-betingelsen op som en JOIN-betingelse? Jeg ved godt hvordan OUTER og INNER fungerer ;)
Avatar billede Slettet bruger
06. april 2006 - 14:33 #8
Det er fint, men du besvarer så ikke spørgsmålet.
Jeg havde brug for alle de posts EN GIVEN BRUGER ikke havde læst :) Og der skal man have fat i et subselect for at det kan komme til at virke :)
Avatar billede barklund Nybegynder
06. april 2006 - 14:34 #9
Jamen. Det er jo netop det min query burde gøre :( Har du prøvet den? :(
Avatar billede barklund Nybegynder
06. april 2006 - 14:37 #10
Konceptet er jo netop som du selv siger at LEFT JOIN'e med alle dem, som han _har_ læst, og derefter finde dem, der netop kun er på den ene side i dette join. Det er præcis, hvad du ønsker, og præcist hvad min query gør. :(
Avatar billede Slettet bruger
11. april 2006 - 00:37 #11
bark problemet er at lave en while. Din sql finder alle posts som INGEN har læst, men jeg vil jo finde alle som en given bruger ikke har læst.
Avatar billede barklund Nybegynder
11. april 2006 - 11:05 #12
Det er nu også, hvad jeg mener den bør gøre. Spørgsmålet er ikke så komplekst igen, så jeg regner med at have forstået det hele :)

Jeg har lige testet på en tilsvarende database-design med queryen:

SELECT *
FROM film_film
LEFT JOIN film_seen ON film_film.f_film_id = film_seen.f_film_id
AND film_seen.f_user_id = 1

Altså hvor der er film_seen og film_film og jeg vil finde alle de film, som brugeren med id=1 _ikke_ har set. Og det virker og giver mig de 25 poster.

:)

--
Morten Barklund
Avatar billede Slettet bruger
20. juni 2006 - 18:40 #13
Status er at denne SQL er den jeg bruger:
SELECT header, traad FROM forum_threads LEFT JOIN (SELECT * FROM forum_readposts WHERE user = 1) forum_readposts ON forum_threads.id = forum_readposts.traad WHERE forum_readposts.traad IS NULL;
Avatar billede Slettet bruger
22. august 2006 - 16:48 #14
Lukker...
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