29. september 2010 - 19:39Der er
12 kommentarer og 1 løsning
SQL beregning
Hej,
Jeg er i tvivl om hvordan jeg nemmest kan lave en løsning, og håber at i kan hjælpe med et bud.
Jeg har et total antal posteringer, som jeg ønsker at dele i 14 lige store dele. Af dem skal jeg finde ud af, hvor mange i hver portion der er indbetalinger.
Hvis der totalt er 100 posteringer, vil en portion være 7 afrundet (7,14) stk. Af dem er første portion måske 1 indbetaling. Næste portion er 2 osv.
Så jeg ender med et resultat, som siger
Indbetalinger=1,2,x,x,x,x,x,x,x,x,x,x,x,x
Kan det laves i en samlet SQL ?
//Antal Select count(*) from posteringer
//Antal indbetalinger Select count(*) from posteringer where type = 'indbetalinger' order by dato
Jeg har lavet et lille test-setup, hvor jeg har lavet en tabel der hedder Posteringer, og så indsætter jeg i alt 100 rækker med bit'en ErIndbetaling til 1, og opdaterer jeg 75 random rækker til at hedde ErIndbetaling 0. Og så har jeg 2 forskellige udtræk, som giver dit ønskede resultat enten som et resultset med 14 rækker, eller som én kommasepareret streng.
Here goes:
--laver test tabel create table Posteringer ( id int identity, ErIndbetaling int )
--Indsætter 100 rækker med ErIndbetaling = 1 insert into Posteringer (ErIndbetaling) values (1) go 100
--Opdaterer 75 random rækker til at hedde ErIndbetaling = 0 update Posteringer set ErIndbetaling = 0 where id in ( select top 75 id from Posteringer order by checksum(newid()) )
--Denne giver dit ønskede resultat som et resultset med 14 rækker, hver med værdien for den tilhørende gruppe. ;WITH CTE AS ( SELECT *, NTILE(14) OVER(ORDER BY id) AS Gruppe FROM Posteringer ) SELECT Gruppe, (SELECT COUNT(*) FROM CTE t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe) AS AntalIndbetalinger FROM CTE t1 GROUP BY Gruppe
--Denne giver dit ønskede resultat som en kommasepareret streng ;WITH CTE AS ( SELECT *, NTILE(14) OVER(ORDER BY id) AS Gruppe FROM Posteringer ), CTE2 AS ( SELECT Gruppe, (SELECT COUNT(*) FROM cte t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe) AS AntalIndbetalinger FROM cte t1 GROUP BY Gruppe ) SELECT SUBSTRING( (SELECT ',' + CAST(AntalIndbetalinger AS VARCHAR(10)) FROM cte2 FOR XML PATH('')),2,200000) AS CSV
ja det tror jeg da, men jeg er ikke lige helt med på hvilke tal der skal stå som procent af det hele.
Hvis den første chunk er på 6 tal, og 2 af dem er indbetalinger, så vil det første tal der returneres være 2. Ønsker du at tallet der returneres i stedet er 33% ?
Eller er det procentsatsen af indbetalinger pr. chunk set mod det samlede antal indbetalinger for alle chunks? Altså hvis strengen returnerer:
Hvad med afrunding? skal det være hele procent, fx 33%, eller skal der x decimaler efter kommaet? Og du vil gerne have %-tegnet med i output'et, altså så det er tekst der returneres i stedet for et tal ?
Nå, jeg fik lige kigget på det med det samme. De samme to queries som før har jeg modificeret. Jeg har antaget at du vil have værdien returneret som "50.0%". Hvis du ikke vil have decimalen med, eller måske vil have flere decimaler, så skal du bare finde det sted hvor jeg i koden laver en CAST til decimal(3,1) og rette til nogle andre værdier. 3 angiver antal tegn i tallet, og 1-tallet angiver hvor mange af disse der er efter kommaet.
--Denne giver dit ønskede resultat som et resultset med 14 rækker, hver med værdien for den tilhørende gruppe. ;WITH CTE AS ( SELECT *, NTILE(14) OVER(ORDER BY id) AS Gruppe FROM Posteringer ) SELECT Gruppe, COUNT(*) AS TotalAntal, (SELECT COUNT(*) FROM CTE t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe) AS AntalIndbetalinger, CAST(CAST((SELECT COUNT(*)*1.0 FROM CTE t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe)/COUNT(*)*100 AS decimal(3,1)) AS VARCHAR(10)) + '%' AS ProcentSats FROM CTE t1 GROUP BY Gruppe
--Denne giver dit ønskede resultat som en kommasepareret streng ;WITH CTE AS ( SELECT *, NTILE(14) OVER(ORDER BY id) AS Gruppe FROM Posteringer ), CTE2 AS ( SELECT Gruppe, COUNT(*) AS TotalAntal, (SELECT COUNT(*) FROM cte t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe)*1.0 AS AntalIndbetalinger, CAST(CAST((SELECT COUNT(*)*1.0 FROM CTE t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe)/COUNT(*)*100 AS decimal(3,1)) AS VARCHAR(10)) + '%' AS ProcentSats FROM cte t1 GROUP BY Gruppe ) SELECT SUBSTRING( (SELECT ',' + CAST((ProcentSats) AS VARCHAR(1000)) FROM cte2 FOR XML PATH('')),2,200000) AS CSV
Jeg er desværre nød til at spørge efter hjælp en gang til :(
Jeg har en anden tabel, som indeholder alt tid forbrugt på de forskellige transaktioner. Hvis jeg ønsker at se hvor mange transaktioner jeg behandler hver time, hvordan kan jeg så få det vist i % (altså eks. er der 10 transaktioner i hver af de 14 perioder, som alle har taget 2 timer at udfører, så det giver 5,5,5,5,5,5,5,5,5,5,5,5,5,5)
Min tids tabel ser ud som "Select * from timer order by create"
Hvis du skal have flere point for at hjælpe må du endelig sige til. Håber meget at du vil hjælpe endnu en gang.
Jeg har prøvet dette, som jeg mener burde virke hvis jeg forstår SQL korrekt. Men den giver en fejl med gruppe
Håber der er en som kan give mig lidt hjælp ?
;WITH CTE AS ( SELECT *, NTILE(14) OVER(ORDER BY create) AS Gruppe FROM timer ), CTE2 AS ( SELECT Gruppe, COUNT(*) AS TotalAntal, (SELECT COUNT(*) FROM posteringer t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe)*1.0 AS AntalIndbetalinger, CAST(CAST((SELECT COUNT(*)*1.0 FROM CTE t2 WHERE t2.ErIndbetaling = 1 AND t1.Gruppe = t2.Gruppe)/COUNT(*)*100 AS decimal(3,1)) AS VARCHAR(10)) AS ProcentSats FROM cte t1 GROUP BY Gruppe ) SELECT SUBSTRING( (SELECT ',' + CAST((ProcentSats) AS VARCHAR(1000)) FROM cte2 FOR XML PATH('')),2,200000) AS CSV
Synes godt om
Ny brugerNybegynder
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.