20. juni 2007 - 23:01Der 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?
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.
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.
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.
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.