2014-09-09 24 views
0

En train d'essayer de créer une requête qui montre combien de comptes ont payé mois par mois mais sur une base cumulative (pénétration). Donc, par exemple, j'ai un tableau avec mois payé et numéro de compte, qui montre quel mois ce compte a payé.SQL cumulatif pour calculer le nombre de payeurs

Month | AccountNo 
Jan-14 | 123456 
Feb-14 | 321654 

Donc, en utilisant ce qui précède le jeu de résultats montreraient

Month | Payers 
Jan-14 | 1 
Feb-14 | 2 

être parce qu'un compte payé en janvier puis un en sens février qu'il y a eu d'ici la fin de février 2 Le total des paiements, mais seulement un en janvier. J'ai essayé quelques inner joins de nouveau sur la table avec un t1.Month >= t2.Month comme je le ferais pour une requête cumulative normale mais le résultat est toujours dehors.

Des questions s'il vous plaît demander, ne sachant pas si ce qui précède sera clair pour tout le monde sauf moi.

+0

Je peux aider- http://www.orafaq.com/node/1874. – FMQB

+0

Avez-vous un champ de date dans ce tableau? –

+0

@KiranHegde Je peux l'ajouter si nécessaire oui. – GPH

Répondre

0

Si vous avez une date dans le tableau, vous pouvez essayer la requête suivante.

SELECT [Month] 
     ,(SELECT COUNT(AccountNo) 
     FROM theTable i 
     -- This is to make sure to add until the last day of the current month. 
     WHERE i.[Date] <= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,o.[Date])+1,0)) AS CumulativeCount 

FROM theTable o 
0

Ok, plusieurs choses. Vous devez avoir un champ de date réel, car vous ne pouvez pas commander par la colonne du mois que vous avez.

que vous devez considérer qu'il peut y avoir des lacunes dans les mois - à savoir quelques mois où il n'y a pas de paiement (pas sûr si cela est vrai ou non)

Je recommande une expression de table commune récursive pour faire la agrégation réelle

Voici comment ça marche:

-- setup 
DECLARE @t TABLE ([Month] NCHAR(6), AccountNo INT) 
INSERT @t ([Month], AccountNo) 
VALUES ('Jan-14',123456),('Feb-14',456789),('Apr-14',567890) 
-- assume no payments in march 

; WITH 
t2 AS  -- get a date column we can sort on 
(
    SELECT [Month], 
     CONVERT(DATETIME, '01 ' + REPLACE([Month], '-',' '), 6) AS MonthStart, 
     AccountNo 
    FROM @t 
), 
t3 AS   -- group by to get the number of payments in each month 
(
    SELECT [Month], MonthStart, COUNT(1) AS PaymentCount FROM t2 
    GROUP BY t2.[Month], t2.MonthStart 
), 
t4 AS   -- get a row number column to order by (accounting for gaps) 
(
    SELECT [Month], MonthStart, PaymentCount, 
     ROW_NUMBER() OVER (ORDER BY MonthStart) AS rn FROM t3 
), 
t5 AS   -- recursive common table expression to aggregate subsequent rows 
(
    SELECT [Month], MonthStart, PaymentCount AS CumulativePaymentCount, rn 
    FROM t4 WHERE rn = 1 
    UNION ALL 
    SELECT t4.[Month], t4.MonthStart, 
     t4.PaymentCount + t5.CumulativePaymentCount AS CumulativePaymentCount, t4.rn 
    FROM t5 JOIN t4 ON t5.rn + 1 = t4.rn 
) 
SELECT [Month], CumulativePaymentCount FROM t5 -- select desired results 

et les résultats ...

Month CumulativePaymentCount 
Jan-14 1 
Feb-14 2 
Apr-14 3 
0

Si la colonne de votre mois est le type de date, il est facile de travailler sur autre chose, vous avez besoin d'une conversion supplémentaire pour cela. Ici la requête va ...

create table example (
MONTHS datetime, 
    AccountNo INT 
) 
GO 

insert into example values ('01/Jan/2009',300345) 
insert into example values ('01/Feb/2009',300346) 
insert into example values ('01/Feb/2009',300347) 
insert into example values ('01/Mar/2009',300348) 
insert into example values ('01/Feb/2009',300349) 
insert into example values ('01/Mar/2009',300350) 


SELECT distinct datepart (m,months), 
    (SELECT count(accountno) 
    FROM example b 
    WHERE datepart (m,b.MONTHS) <= datepart (m,a.MONTHS)) AS Total FROM example a