Vad du egentligen behöver är att tillfälligt låtsas att c2.reading
gick inte runt efter att ha nått 1 000 000, och det bara när c2.reading < c1.reading
. Det vill säga, vid den tidpunkten skulle du behöva öka c2.reading
med 1 000 000, subtrahera sedan c1.reading
. Och när c2.reading >= c1.reading
, bör frågan beräkna den "normala" skillnaden, dvs subtrahera c1.reading
från den ursprungliga (icke-ökade) c2.reading
värde.
Ett sätt att uppnå den logiken skulle vara att göra något så enkelt som detta:
SUM(
CASE WHEN c2.reading < c1.reading THEN 1000000 ELSE 0 END
+ c2.reading
- ISNULL(c1.reading, c2.reading)
) AS Count1
Men det finns också ett annat tillvägagångssätt.
Dina avläsningsvärden, och, som en konsekvens, även skillnader mellan två av dem, kan aldrig överstiga 1 000 000. Därför kan du fritt använda modulo 1 000 000 till en positiv skillnad och det ger dig samma skillnad tillbaka:
d mod 1,000,000 = d
Att lägga till multiplar av 1 000 000 till en positiv skillnad kommer dessutom inte att påverka resultatet av modulo 1 000 000 eftersom, enligt modulo-operationens fördelningsförmåga,
(d + 1,000,000 * n) mod 1,000,000 =
= d mod 1,000,000 + (1,000,000 * n) mod 1,000,000
Den första summan, d mod 1,000,000
resulterar i d
, den andra, (1,000,000 * n) mod 1,000,000
ger 0, d + 0 = d
.
Å andra sidan, lägga till 1 000 000 till ett negativt skillnad skulle ge oss en korrekt positiv skillnad.
Så, för att sammanfatta,
-
lägga till 1 000 000 till en negativ skillnad ger oss en (korrekt) positiv skillnad,
-
en positiv skillnad modulo 1 000 000 ger samma positiva skillnad, och
-
att lägga till 1 000 000 till en positiv skillnad påverkar inte resultatet av modulo 1 000 000.
Med hänsyn till allt detta kan vi sluta med följande universella uttryck för att beräkna en enda skillnad:
(1000000 + c2.reading - ISNULL(c1.reading, c2.reading)) % 1000000
där %
är modulo-operatören i Transact- SQL
.
Lägg uttrycket i SUM
för att få motsvarande aggregerade värden:
SUM((c2.reading + 1000000 - ISNULL(c1.reading, c2.reading)) % 1000000) AS Count1