webForumDet fria alternativet

Göra allt i en fråga?

Databaser & SQL

8 svar · 604 visningar · startad av johgu

Medlem sedan feb. 200732 inlägg
Frågan#1

Jag har en tabell som ser ut:

[ID] [År]
1 2006
1 2006
1 2006
2 2006
1 2004
2 2004

Nu vill jag få ut resultat enligt följande:

ID ANTAL

2004 totalt: 2
----------
1 1
2 1

2006 totalt: 4
----------
1 3
2 1

Är detta möjligt att göra i en enda fråga?

Medlem sedan dec. 19996 721 inlägg
#2

johgu skrev:

Är detta möjligt att göra i en enda fråga?

Javisst (med det är bättre att fråga i SQL-forumet. Det har inte med ASP att göra).

SELECT ID,År,COUNT(*),(SELECT COUNT(*) FROM tabellen t2 WHERE t1.År=t2.År) as Total FROM tabellen t1
GROUP BY ID, År
Medlem sedan feb. 200732 inlägg
#3

Tack för ett snabbt svar. Problemet är bara att databasen innehåller > 100 000 poster och det tar för lång tid att köra den frågan. Finns det något sätt att optimera?

Medlem sedan feb. 200112 078 inlägg
#4

Låt databasen göra sin beräkning, det är det den är bra på, även om skalärfunktioner kanske inte är det mest optimala. Visa ett litet timglas eller nåt istället; 100.000 rader är inte så farligt ändå.

Medlem sedan juni 20008 205 inlägg
#5

En ännu bättre idé är att inte köra allt i en fråga. Normalt ska man försöka köra så få frågor som möjligt, men ur exekveringssynpunkt är det här inte en fråga, eftersom subselecten gör att det blir en fråga per rad i databasen. Även om selecten i sig är ganska lättviktig om år-kolumnen är indexerad är det klart suboptimalt och ska undvikas om det går. I det här fallet vore det klart effektivare att ställa två frågor om du inte har helt sinnessjuk latens mellan din applikation och databasen (typ, om den ena av burkarna står bakom ett 300-bauds modem...).

Medlem sedan feb. 200732 inlägg
#6

Ok. Vilka två frågor skulle du ställt isf?

Tänkte göra ett test och se vad som blir snabbast.

Medlem sedan juni 20003 076 inlägg
#7

Om du ska få det snabbt så är det OveRRidEs förslag som gäller, låt databasen göra uträkningen.
Hur du gör det beror på vilken typ av databas du kör men i t.ex. SQL Server så bygger man en vy för detta. :)

Medlem sedan juni 20008 205 inlägg
#8

Först väljer du fram antal rader/id/år med SELECT id, år, COUNT(*) AS antal FROM tabellen GROUP BY id, år ORDER BY år, id och sen hämtar du totalt antal id/år med SELECT år, COUNT(*) AS antal FROM tabellen GROUP BY år ORDER BY år. Sen får du loopa igenom det första resultatet, och på varje rad som inte har samma år som den föregående raden (inklusive den första) får du hämta ut nästa rad ur resultatet av den andra frågan och skriva ut en rubrik. Pseudokod:

idResult = (ställ frågan [I]SELECT id, år, COUNT(*) AS antal FROM tabellen GROUP BY id, år ORDER BY år, id[/I] till databasen)
yearResult = (ställ frågan [I]SELECT år, COUNT(*) AS antal FROM tabellen GROUP BY år ORDER BY år[/I] till databasen)
previousYear = "godtyckligt ogiltigt värde för ett årtal"
while (vi har inte passerat sista raden i idResult)
    if (idResult("år") <> previousYear)
        skriv ut yearResult("år") & " totalt: " & yearResult("antal")
        previousYear = idResult("år")
        gå till nästa rad i yearResult
    end if 
    skriv ut idResult("id") & " " & idResult("antal")
    gå till nästa rad i idResult
end while
Medlem sedan dec. 200012 464 inlägg
#9

Flyttas från asp

259 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
135 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)