Avatar billede fanatic Nybegynder
20. juni 2007 - 23:01 Der er 7 kommentarer og
1 løsning

Udtræk tråde og datoen på nyeste post i trådene på et diskussions

Hej eksperter.

Jeg har en simpelt Access database som indeholder data til et diskussionsforum. Dertil vil jeg gerne have vist alle trådene i forummet på min hjemmeside.

Dette fungere fint vha følgende SQL:

SELECT t.*, m.username FROM Thread t, Member m WHERE m.memberId = t.threadCreatorId ORDER BY t.threadDate DESC"

Herved får jeg hentet info om trådene og den bruger der har oprettet dem hver især. Det virker fint!

MIT PROBLEM:
Jeg havde tænkt at ved siden af hver tråd skal der stå datoen på den senest oprettet post i tråden. Så behøver man jo ikke klikke på tråden for at se om der er sket noget nyt men kan blot se det ud fra datoen.

Hvordan gør jeg mon det? Jeg har førsøgt med følgende SQL:

SELECT t.*, Max(p.postDate) as MaxPostDate, m.username
FROM Thread t, Post p, Member m
WHERE t.threadId = p.postThreadId AND m.memberId = t.threadCreatorId ORDER BY t.threadDate DESC

Jeg får dog fejlen:
"You tried to execute a query that does not include the specified expression 'threadId' as part of an aggregate function. (Error 3122)

Min tanke bag SQL'en er at udtage data om tråden og brugeren der oprettede den, samt datoen på den post med den nyeste dato "Max(p.postDate)", men et eller andet gør jeg galt, hvad mon?

Til eksemplet benytter jeg følgende tabeller:

Thread:
|threadId|threadSubject|threadCreatorId|threadDate|...|...

Post:
|postId|postBody|postThreadId|postCreatorId|postDate|....|..

Member:
|memberId|...|....

Er der en som kan fortælle mig hvad jeg gør galt?
Avatar billede fdata Forsker
20. juni 2007 - 23:39 #1
Del det op i to forespørgsler:
1) En SumForespørgsel, der giver dig postID og Max(p.postDate)
2) Din "gamle" forespørgsel, hvor du lige linker 1) ind via postID
Hvis du arbejder direkte med SQL udtryk, kan du oprette forespørgslen i Access' grafiske designværktøj og så klikke på Vis/SQL og stjæle SQL udtrykket her.
Avatar billede kjulius Novice
21. juni 2007 - 00:50 #2
Din SQL er sådan set i orden, men du har glemt en meget basal ting: Så snart du bruger en aggregat funktion (MIN, MAX, AVG osv.) skal alle andre felter, som ikke bruger en aggregat funktion stå i en GROUP BY del. Sådan er det i Access og de allerfleste andre databaser. Jeg er bevidst om, at MySQL ikke overholder standard SQL på dette punkt, så hvis du er vant til at arbejde med den database, er du undskyldt, ellers ikke. :-)

Det er dette din fejlmelding forsøger at formidle. Da threadId ikke er en del af en aggregat funktion, skal den stå i GROUP BY delen. Hvis du kun sætter dette felt på en GROUP BY, vil du dog opleve, at det så bare er det næste felt der klages over. Du er nødt til at angive alle felter, som ikke benytter en aggregat funktion i din GROUP BY. Afhængig af hvor mange felter du ønsker at returnere kan det blive til en del.

SELECT t.*, Max(p.postDate) as MaxPostDate, m.username
FROM Thread t, Post p, Member m
WHERE t.threadId = p.postThreadId AND m.memberId = t.threadCreatorId
GROUP BY t.*, m.username
ORDER BY t.threadDate DESC
(bemærk, at du ,så vidt jeg husker, skal erstatte t.* med de faktiske feltnavne i GROUP BY)

Alternativt kan du anvende en nestet forespørgsel (Access understøtter nestede forespørgsler i 1 niveau, så det går lige):

SELECT t.*, p.MaxPostDate, m.username
FROM Thread t, (SELECT postThreadId, MAX(postDate) as MaxPostDate FROM Post GROUP BY postTreadId) p, Member m
WHERE t.threadId = p.postThreadId AND m.memberId = t.threadCreatorId ORDER BY t.threadDate DESC

Det er i princippet det samme som fdata foreslår, bare gjort på en anden måde. Hvor han foreslår dig at bruge statiske forespørgsler oprettede i Access, bruger min dynamiske, nestede forespørgsler.
Avatar billede fanatic Nybegynder
22. juni 2007 - 12:30 #3
tak for hjælpen....

kjulius>> I første eksempel, det virker - dog skal t.threadDate jo også stå under Group By ifølge det du siger ;-)

Hvad er mest korrekt "nested" eller ej? Performer den ene bedre end den anden?
Avatar billede fanatic Nybegynder
22. juni 2007 - 13:30 #4
Ok..det virker med følgende som kjulius foreslog:

SELECT t.threadSubject, t.threadCreatorId, t.threadDate, t.threadId, Max(p.postDate) as maxPostDate, m.username
FROM Thread t, Post p, Member m
WHERE t.threadId = p.postThreadId AND m.memberId = t.threadCreatorId
GROUP BY t.threadSubject, t.threadCreatorId, t.threadDate, t.threadId, m.username
ORDER BY t.threadDate DESC

Hvis jeg nu kunne tænke mig også at få "navnet" på ham der har oprettet den seneste post i hver tråd, hvordan ville man gøre det(jeg har jo brugt username én gang)? Jeg går ud fra at p.postCreatorId skal bruges her.
Avatar billede kjulius Novice
23. juni 2007 - 12:37 #5
Du kan godt referere til de samme feltnavne, bare du navngiver dem forskelligt i din SELECT, f.eks.

SELECT t1.name AS t1Name, t1.name AS t1Name2, t2.Name as t2Name
FROM tabel1 t1, tabel2 t2

Som du kan se, kan du endog selektere det samme felt fra samme tabel, bare du navngiver dem forskelligt.
Avatar billede kjulius Novice
02. august 2007 - 17:37 #6
Var vi færdige?
Avatar billede fanatic Nybegynder
28. august 2007 - 12:59 #7
Tak for hjælpen!!! Beklager den sene tilbagemelding, jeg blev lige optaget af noget andet ;-)
Avatar billede kjulius Novice
30. august 2007 - 12:06 #8
Helt i orden... :-)
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
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

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