Co v podstatě potřebujete, je dočasně předstírat, že c2.reading
neobtékal po dosažení 1 000 000, a to pouze při c2.reading < c1.reading
. To znamená, že v tomto okamžiku budete muset zvýšit c2.reading
o 1 000 000, poté odečtěte c1.reading
. A když c2.reading >= c1.reading
, dotaz by měl vypočítat "normální" rozdíl, tj. odečíst c1.reading
z původního (nezvětšeného) c2.reading
hodnotu.
Jedním ze způsobů, jak této logiky dosáhnout, by bylo udělat něco tak přímočarého, jako je toto:
SUM(
CASE WHEN c2.reading < c1.reading THEN 1000000 ELSE 0 END
+ c2.reading
- ISNULL(c1.reading, c2.reading)
) AS Count1
Existuje však také jiný přístup.
Vaše naměřené hodnoty a v důsledku toho i rozdíly mezi kterýmikoli dvěma z nich nemohou nikdy překročit 1 000 000. Proto můžete volně použít modulo 1 000 000 na kladný rozdíl a to vám vrátí stejný rozdíl:
d mod 1,000,000 = d
Navíc přidání násobků 1 000 000 ke kladnému rozdílu neovlivní výsledek modulo 1 000 000, protože podle distributivity operace modulo
(d + 1,000,000 * n) mod 1,000,000 =
= d mod 1,000,000 + (1,000,000 * n) mod 1,000,000
První součet, d mod 1,000,000
výsledkem je d
, druhý, (1,000,000 * n) mod 1,000,000
dává 0, d + 0 = d
.
Na druhou stranu přičtení 1 000 000 k zápornému číslu rozdíl by nám dal správný kladný rozdíl.
Takže, abych to shrnul,
-
přičtením 1 000 000 k zápornému rozdílu získáme (správný) kladný rozdíl,
-
kladný rozdíl modulo 1 000 000 dává stejný kladný rozdíl a
-
přidání 1 000 000 ke kladnému rozdílu neovlivní výsledek modulo 1 000 000.
Když to všechno vezmeme v úvahu, můžeme skončit s následujícím univerzálním výrazem pro výpočet jediného rozdílu:
(1000000 + c2.reading - ISNULL(c1.reading, c2.reading)) % 1000000
kde %
je modulo operátor v Transact- SQL
.
Vložte výraz do SUM
získat odpovídající agregované hodnoty:
SUM((c2.reading + 1000000 - ISNULL(c1.reading, c2.reading)) % 1000000) AS Count1