DECLARE @MD AS int;
SELECT @MD = MAX(YEAR(a2.STARTTIME) * 100 + MONTH(a2.ENDTIME)) FROM ashtable a2;
WITH MTHS AS (
SELECT MIN(YEAR(STARTTIME) * 100 + MONTH(STARTTIME)) TheMonth FROM ashtable
UNION ALL
SELECT TheMonth + 1 FROM MTHS WHERE TheMonth < @MD
),
ALLMONTHS AS
(
select a.Column1,a.column2,m.TheMonth, SUM(FACTOR) f from mths m
LEFT JOIN
ashtable a
ON m.TheMonth >= YEAR(a.STARTTIME) * 100 + MONTH(a.STARTTIME)
AND
m.TheMonth <= YEAR(a.ENDTIME) * 100 + MONTH(a.ENDTIME)
GROUP BY a.Column1,a.column2, m.TheMonth
),
RNS AS
(SELECT a.Column1,a.column2,a.TheMonth, a.f, a.f - COALESCE(b.f, -99999999.99) dif FROM ALLMONTHS a
LEFT JOIN ALLMONTHS b ON a.TheMonth = b.TheMonth + 1 AND a.column1=b.column1 and a.column2=b.column2),
ISLANDS AS (
select a.Column1,a.column2,a.TheMonth,
MIN(b.TheMonth) MonthEnd,
MIN(A.f) Factor
from RNS a
LEFT JOIN RNS b ON a.column1=b.column1 and a.column2=b.column2 and b.TheMonth > a.TheMonth AND b.f <> a.f WHERE a.dif <> 0
GROUP BY a.column1,a.column2,a.TheMonth
)
SELECT Column1,column2,dateadd(month, (themonth - 1) % 100,
DateADD(year,(Themonth)/100 - 1900, 0)) s,
dateadd(day,-1,dateadd(month, (themonth) % 100,
DateADD(year,(Themonth)/100 - 1900, 0))) e, factor FROM ISLANDS order by column1,column2,s
meiner Ausgabe (einschließlich einer Testreihe für verschiedene Spaltenschlüssel)
Column1 column2 s e factor
---------- ---------- ----------------------- ----------------------- -------
A B 2016-01-01 00:00:00.000 2016-01-31 00:00:00.000 0.7
A B 2016-02-01 00:00:00.000 2016-02-29 00:00:00.000 1.0
A B 2016-03-01 00:00:00.000 2016-03-31 00:00:00.000 1.2
A B 2016-07-01 00:00:00.000 2016-07-31 00:00:00.000 0.5
A B 2016-09-01 00:00:00.000 2016-09-30 00:00:00.000 0.3
A C 2016-01-01 00:00:00.000 2016-01-31 00:00:00.000 99.0
hier ist eine modifizierte Version, meine gescheiterten Ideen repräsentieren Jahr Monat als Integer
DECLARE @MD AS datetime;
SELECT @MD = MAX(endtime) FROM ashtable a2;
WITH MTHS AS (
SELECT MIN(STARTTIME) TheMonth FROM ashtable
UNION ALL
SELECT dateadd(month,1,TheMonth) TheMonth FROM MTHS WHERE TheMonth < @MD
),
ALLMONTHS AS
(
select a.Column1,a.column2,m.TheMonth, SUM(FACTOR) f from mths m
LEFT JOIN
ashtable a
ON m.TheMonth >= a.starttime
AND
m.TheMonth < a.endtime
GROUP BY a.Column1,a.column2, m.TheMonth
),
RNS AS
(SELECT a.Column1,a.column2,a.TheMonth, a.f, a.f - COALESCE(b.f, -99999999.99) dif FROM ALLMONTHS a
LEFT JOIN ALLMONTHS b ON a.TheMonth = dateadd(month,1,b.TheMonth) AND a.column1=b.column1 and a.column2=b.column2),
ISLANDS AS (
select a.Column1,a.column2,a.TheMonth,dq2.lastmonth,a.f factor
from RNS a
CROSS APPLY
(SELECT TOP 1 * FROM (SELECT 1 as ord, b.TheMonth lastmonth FROM RNS b WHERE a.Column1 = b.column1 and a.column2=b.column2 and b.themonth>a.themonth and a.f <> b.f
union SELECT 2 as ord, dateadd(month,1,max(c.themonth)) lastmonth from rns c where a.Column1 = c.column1 and a.column2=c.column2) dq ORDER BY DQ.ord) dq2
where a.dif<>0
--MIN(b.TheMonth) MonthEnd,
--MIN(A.f) Factor
-- from RNS a
-- LEFT JOIN RNS b ON a.column1=b.column1 and a.column2=b.column2 and b.TheMonth > a.TheMonth AND b.f <> a.f where a.dif<>0
-- GROUP BY a.column1,a.column2,a.TheMonth
)
SELECT Column1,column2,themonth, dateadd(day,-1,lastmonth),
factor FROM ISLANDS order by column1,column2,themonth
Wegwerfen es ist die gleiche Ausgabe und Daten präsentiert .. Details? –
Wie ist Mar June Faktor cacluated – TheGameiswar
Wie werden Ihre Start- und Endzeiten gehalten? Sind sie Daten oder nur Text? Wenn es Text ist, wird dort ein Jahr gehalten? Ich glaube, der Fragesteller möchte die Faktoren zusammenfassen, wenn es eine Überschneidung gibt. Wenn Sie also eine Tabelle mit Monaten, 1-12, hätten, könnten Sie alle Faktoren, die in diesen Bereich fallen, summieren (obwohl die angezeigten Daten Text für Monatsnamen verwenden). Das Rekombinieren von Summen für 1-12 ist ein "Insel" -Problem, das mit WITH, row_number, einem Self-Join zur vorherigen Zeile und der Erkennung von Änderungspunkten gelöst werden kann. – Cato