NLDelphi logo

Apada
Start Forum Nieuws Artikelen Links E mail Statistieken
NLDelphi partnersite: nlDotnet
NLDelphi

Ga Terug   NLDelphi > Vraagbaak > Databases

Antwoord
 
Onderwerpopties Zoek in onderwerp Stem op Onderwerp Weergavemodus
Oud 04-May-12, 17:15   #1
Henk6a
Senior Member
 
Geregistreerd op: Mar 2003
Berichten: 102
MSSQL Bepalen waar cum. aantal door de nul gaat

Ik heb een MSSQL tabel met datums en aantallen

13-01-2012 200
15-01-2012 300
17-01-2012 1200
18-01-2012 -1500
21-01-2012 500
23-01-2012 -1500
25-01-2012 500


Ik zoek nu dus de datum waar het cumulatieve som van de aantallen van positief naar negatief gaat en/of andersom.

Het liefst zou ik dit mbv een sql query oplossen

Heeft iemand een idee hoe dit op te lossen?
Henk6a is offline   Met citaat antwoorden
Oud 05-May-12, 00:14   #2
evert
Senior Member
 
evert's Avatar
 
Geregistreerd op: Sep 2004
Locatie: Amsterdam
Berichten: 562
Code:
SELECT DTDV.Vorige_datum, CumAantalV, DTDV.datum, CumAantal FROM
(SELECT a1.datum, Max(a2.datum) AS Vorige_datum
FROM AantalPerDatum AS a1, AantalPerDatum AS a2
WHERE a2.datum < a1.datum
GROUP BY a1.datum) DTDV,
(Select a1.datum, sum(a2.aantal) as CumAantal
from AantalPerDatum a1, AantalPerDatum a2
where a2.datum <= a1.datum
group by a1.datum) CUM1,
(Select a1.datum, sum(a2.aantal) as CumAantalV
from AantalPerDatum a1, AantalPerDatum a2
where a2.datum <= a1.datum
group by a1.datum) CUM2
WHERE DTDV.datum = CUM1.datum AND DTDV.Vorige_Datum = CUM2.datum
AND ((CumAantal > 0 AND CumAantalV <= 0) Or (CumAantal <= 0 AND CumAantalV > 0))
evert is offline   Met citaat antwoorden
Oud 08-May-12, 16:25   #3
chamers
Registered User
 
Geregistreerd op: Feb 2006
Locatie: Oss
Berichten: 17
Vanaf de SQL/2003 standaard zou je dit met een WINDOW clause op kunnen lossen (getest mbv Sybase SQL AnyWhere 11)

Hiervoor heb ik de volgende test tabel aangemaakt:
Code:
create table test (
datum date,
aantal integer
);

insert into test (datum, aantal) values ('2012-01-13', 200);
insert into test (datum, aantal) values ('2012-01-15', 300);
insert into test (datum, aantal) values ('2012-01-17', 1200);
insert into test (datum, aantal) values ('2012-01-18', -1500);
insert into test (datum, aantal) values ('2012-01-21', 500);
insert into test (datum, aantal) values ('2012-01-23', -1500);
insert into test (datum, aantal) values ('2012-01-25', 500);
En als ik het goed begrijp wil je dus de Sum hebben van het aantal t/m vandaag:
Code:
select datum, 
       Sum(aantal) over (rows between unbounded preceding and current row) as TotaalTotEnMetDatum
  from test
 order by datum asc;
Result:
13-01-2012 200
15-01-2012 500
17-01-2012 1700
18-01-2012 200
21-01-2012 700
23-01-2012 -800
25-01-2012 -300

En dan kun je dus vervolgens op deze manier bepalen op welke datum dat aantal voor het eerst < 0 wordt:
Code:
select top 1 datum
  from (select datum, 
               Sum(aantal) over (rows between unbounded preceding and current row) as TotaalTotEnMetDatum
          from test
         order by datum) as tempResult
 where TotaalTotEnMetDatum < 0
 order by datum asc;
chamers is offline   Met citaat antwoorden
Oud 08-May-12, 19:43   #4
Henk6a
Senior Member
 
Geregistreerd op: Mar 2003
Berichten: 102
@evert krijg het nog niet voor elkaar, geeft bij mij geen resultaten. Misschien doe ik nog iets fout.

@chamers Helaas werkt dit niet op MSSQL 2008


Ik zit er over te denken om te upgraden naar MSSQL 2012. Deze kent nl de over constructie
Henk6a is offline   Met citaat antwoorden
Oud 08-May-12, 20:35   #5
evert
Senior Member
 
evert's Avatar
 
Geregistreerd op: Sep 2004
Locatie: Amsterdam
Berichten: 562
Citaat:
Origineel gepost door Henk6a Bekijk Bericht
@evert krijg het nog niet voor elkaar, geeft bij mij geen resultaten. Misschien doe ik nog iets fout.
Geeft hij dan een foutmelding?
evert is offline   Met citaat antwoorden
Oud 10-May-12, 11:56   #6
Henk6a
Senior Member
 
Geregistreerd op: Mar 2003
Berichten: 102
Nee, maar ik kreeg geen resultaten, terwijl die er wel zouden moeten zijn

heb inmiddels sql2012 geinstalleerd en ga daar nu eerst mee stoeien
Henk6a is offline   Met citaat antwoorden
Oud 10-May-12, 12:53   #7
chamers
Registered User
 
Geregistreerd op: Feb 2006
Locatie: Oss
Berichten: 17
Zie trouwens dat ik nog een foutje had zitten in m'n voorbeeld.
De order by moet je al zetten in de OVER clause.

Code:
select top 1 datum
  from (select datum, 
               Sum(aantal) over (order by datum rows between unbounded preceding and current row) as TotaalTotEnMetDatum
          from test) as tempResult
 where TotaalTotEnMetDatum < 0
 order by datum asc;
chamers is offline   Met citaat antwoorden
Oud 10-May-12, 22:44   #8
evert
Senior Member
 
evert's Avatar
 
Geregistreerd op: Sep 2004
Locatie: Amsterdam
Berichten: 562
Citaat:
Origineel gepost door Henk6a Bekijk Bericht
Nee, maar ik kreeg geen resultaten, terwijl die er wel zouden moeten zijn
Ik heb het in MSAccess uitgevogeld. Zie bijlage en screenshot.

Bijgesloten Bestanden
Bestandstype: zip Cumuleren_SQL.zip (17,1 KB, 29x gelezen)
evert is offline   Met citaat antwoorden
Oud 11-May-12, 00:25   #9
Henk6a
Senior Member
 
Geregistreerd op: Mar 2003
Berichten: 102
Dit is het geworden:

SELECT MAX(TR.TradeDate)
FROM (SELECT Tradedate,Quantity,
SUM(Quantity) OVER (ORDER BY Tradedate ROWS 1 PRECEDING ) AS Cumvorige,
SUM(Quantity) OVER (ORDER BY Tradedate) AS Cumaantal
FROM transacties) TR
WHERE (TR.CumVorige <= 0 AND TR.CumAantal >= 0) OR (TR.CumVorige >= 0 AND TR.CumAantal <= 0)
Henk6a is offline   Met citaat antwoorden
Antwoord

Bookmarks


Momenteel bekijken: 1 (0 leden en 1 gasten en/of zoekmachine bots) actieve gebruikers dit onderwerp
 
Onderwerpopties Zoek in onderwerp
Zoek in onderwerp:

Geavanceerd zoeken
Weergavemodus Stem op dit onderwerp:
Stem op dit onderwerp::

Berichting Regels
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Aan
Smilies zijn Aan
[IMG] code is Aan
HTML code is Uit

Forumnavigatie


Alle tijden zijn GMT +2. De tijd is nu 20:00.


Forum software: vBulletin, versie 3.8.6
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Copyright ©2011, NLDelphi.com (Dutch Delphi programming)