Avatar billede javanic Nybegynder
02. november 2007 - 11:04 Der er 11 kommentarer

Distinct på flere kolonner - TOP 10 liste

Hej

Jeg har et lille problem, som jeg håber der er en enkelt herinde der kan hjælpe mig med. Jeg har
nedenstående tre tabeller (som dog er forkortet lidt her, rent indholdmæssigt)
------------------

Forum:
    ID
      Name

Thread:
    ID,
    ForumID,
    Title,
    Text,
    Date

ThreadEntry:
    ID,
    ThreadID,
    Text,
    Date



Nu vil jeg så godt lave to forskellige TOP 10 (DISTINCT) lister med de Forum,

1) hvor der har været den "seneste/nyeste" aktivitet
(den seneste Thread, eller ThreadEntry)

...samt

2) hvor der har været MEST aktivitet - totalt.
(aktiviteten måles i antallet af Threads og ThreadEntries)


Listen jeg vil have ud skal være på formen:


ForumID    ForumName ThreadID ThreadTitle ThreadDate
------------------------------------------------------------------
1    ForumA      189      abc        02-11-2007 08:50:34
56    ForumG      239      asd        02-11-2007 08:34:34
47    ForumD      320      qwe        02-11-2007 06:25:57



jeg håber ikke at det er sort snak, så der er en enkelt eller flere der kan hjælpe mig i mål.

på forhånd tak
:o)
Avatar billede javanic Nybegynder
02. november 2007 - 12:34 #1
ingen der har rodet med lignende udtræk? :)
Avatar billede dr_chaos Nybegynder
02. november 2007 - 14:30 #2
Måske noget i denne stil :
SELECT TOP 10  ForumID    ForumName ThreadID ThreadTitle ThreadDate , MAX(te.Date)
FROM forum f
JOIN Thread t ON t.FOrumID = f.ID
JOIN ThreadEntry te ON te.ThreadID = t.ID
ORDER BY te.Date DESC , t.Date DESC
GROUP BY ForumID    ForumName ThreadID ThreadTitle ThreadDate
Avatar billede javanic Nybegynder
02. november 2007 - 15:08 #3
hej dr_chaos,

kigger på det med det samme. :-)
Avatar billede kjulius Novice
03. november 2007 - 00:04 #4
Mit forslag ville nærmere lyde nogenlunde sådan:

SELECT TOP 10 f.ForumID, f.ForumName, t.ThreadId, t.TheadTitle, t.LastActivity
FROM Forum f
INNER JOIN (
  SELECT t.ForumId, t.ID AS ThreadId, t.Title AS ThreadTitle, COALESCE(MAX(te.Date), MAX(t.Date)) AS LastActivity
  FROM Thread t
  LEFT JOIN ThreadEntry te ON t.ID = te.ThreadID
  GROUP BY t.ForumId, ThreadId, ThreadTitle
) t ON f.Id = t.ForumID
ORDER BY t.LastActivity DESC

men det er ikke noget jeg har testet...
Avatar billede javanic Nybegynder
03. november 2007 - 12:30 #5
hej kjulius.

det virker fint - dog ønsker jeg kun at et Forum kan optræde én enkelt gang på listen, da jeg vil undgå at det samme Forum optræder på "top listens" alle 10 pladser.


ID    ForumName    ThreadID Title        LastActive
-----------------------------------------------------------------------
70    forum_a        135    Julefrokost    2007-11-03 04:14:17.120
70    forum_a        133    Valg        2007-11-03 04:06:08.480
54    forum_www    132    Weekend...    2007-11-03 04:04:56.197
70    forum_a        130    hvem vinder?    2007-11-03 04:01:24.043
...


kan ikke umiddelbart bruge distinct, da rækkerne jo reelt er forskellige, så leger lidt med at temp-tabel - er det ikke den rigtige fremgangsmåde?
Avatar billede kjulius Novice
03. november 2007 - 23:31 #6
Hmmm... Det krav gør det jo ikke ligefrem nemmere. :-)

Hvad siger du til denne her?

SELECT TOP 10 f.ForumID, f.ForumName, t.ThreadId, t.TheadTitle, txx.LastActivity
FROM Forum f
INNER JOIN (
  SELECT t.ForumId, MAX(t.ThreadId) AS ThreadId, t.LastActivity
  FROM Thread t
  INNER JOIN (
    SELECT t.ForumId, COALESCE(MAX(te.Date), MAX(t.Date)) AS LastActivity
    FROM Thread t
    LEFT JOIN ThreadEntry te ON t.ID = te.ThreadID
    GROUP BY t.ForumId
    ) tx ON t.ForumId = tx.ForumID
  LEFT JOIN Thread t ON f.Id = t.ForumID AND t.Date = tx.LastActivity
  GROUP BY t.ForumId, t.LastActivity
) txx ON f.ForumId = txx.ForumId
LEFT JOIN Thread t ON t.ForumId = txx.ForumId AND t.Id = txx.ThreadId
ORDER BY txx.LastActivity DESC

(igen, ikke testet).
Avatar billede javanic Nybegynder
03. november 2007 - 23:42 #7
nemmere - nej det ved jeg ;-) ...er også lidt overrasket over at det tilsyneladende ikke er så lige til, som jeg havde troet. Prøver lige at give det et forsøg.

tak for input - vender lige tilbage når jeg har testet...
Avatar billede kjulius Novice
04. november 2007 - 01:09 #8
Hov, opdager lige, at der står t.LastActivity i SELECT på niveau 2 i forespørgslen - det skal i hvert fald være tx.LastActivity

(dog, stadig ikke testet)
Avatar billede javanic Nybegynder
04. november 2007 - 02:05 #9
hmmm... kan ikke helt få det til at spille. tror muligvis at der er rod med et alias:

Msg 1011, Level 16, State 1, Line 1
The correlation name 't' is specified multiple times in a FROM clause.

:-/
Avatar billede HenrikSjang Nybegynder
07. marts 2008 - 22:45 #10
Et bud kunne være noget i denne stil:
Det her kigger godt nok kun på hvornår den senete ThreadEntry har været, og altså ikke på selve Thread'en. Dvs, at hvis man kan oprette 10 Thread's, uden at lave ThreadEntries, så vil Foraet ikke stå som værende hyppigst brugt.

Men tag et kig på:
WITH Forum_CTE
AS
(
SELECT
    Forum.id,
    Forum.name AS ForumName,
    Thread.id AS ThreadID,
    Thread.Title AS ThreadTitle,
    ThreadEntry.Date AS ThreadDate,
    ROW_NUMBER() OVER(PARTITION BY Forum.id ORDER BY ThreadEntry.Date DESC) AS RowNumber
FROM Forum
INNER JOIN Thread ON Forum.id = Thread.ForumID
INNER JOIN ThreadEntry ON Thread.id = ThreadEntry.ThreadID
)
SELECT TOP 10 id, ForumName, ThreadID, ThreadTitle, ThreadDate
FROM Forum_CTE
WHERE RowNumber = 1
ORDER BY ThreadDate DESC


Den anden del af dit spørgsmål, har jeg også et bud på. Her har jeg også kun talt antal ThreadEntries sammen, og lister foraene sorteret efter max antal ThreadEntries. Jeg har i dette forslag kun selectet Forum.id samt Forum.navn ud, da jeg jo ikke ved hvilken Thread samt ThreadEntry du er interesseret i at vide.

SELECT
    Forum.id,
    Forum.name AS ForumName,
    COUNT(*) as antal
FROM Forum
INNER JOIN Thread ON Forum.id = Thread.ForumID
INNER JOIN ThreadEntry ON Thread.id = ThreadEntry.ThreadID
GROUP BY Forum.id, Forum.name
ORDER BY 3 DESC

--------
Hvis du vil have rækkerne returneret, så de indeholder forum, thread samt threadEntry info, så kan man vælge at ville se den nyeste Entry fra hvert forum, og så blot sortere efter max antal. Det kan gøres sådan her:

WITH Activity_CTE
AS
(
SELECT
    Forum.id AS id,
    Forum.name AS ForumName,
    Thread.id AS ThreadID,
    Thread.Title AS ThreadTitle,
    ThreadEntry.Text AS ThreadEntryText,
    ThreadEntry.Date AS ThreadEntryDate,
    RANK() OVER(PARTITION BY Forum.ID ORDER BY Thread.ID) AS Rank
FROM Forum
INNER JOIN Thread ON Forum.id = Thread.ForumID
INNER JOIN ThreadEntry ON Thread.id = ThreadEntry.ThreadID
)

SELECT
    id,
    ForumName,
    ThreadId,
    ThreadTitle,
    ThreadEntryText,
    MAX(ThreadEntryDate),
    COUNT(*) AS Antal FROM Activity_CTE
GROUP BY id, ForumName, ThreadID, ThreadTitle, ThreadEntryText, Rank
ORDER BY 6 DESC


Håber det giver mening, for så kan du selv tilføje relevante kolonner i udtrækket. Ellers må du spørge igen :)
Avatar billede javanic Nybegynder
20. januar 2009 - 22:00 #11
:-) ...ja,...den er jo lidt gammel denne her. Men det endte også med noget i den stil du skriver. Smid et svar, så får du point. Tak fordi din tid , sjang
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