Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Разликата между стойностите на всеки ред - грешка в сумата

Това, от което се нуждаете, е временно да се преструвате, че c2.reading не се уви след достигане на 1 000 000 и това само когато c2.reading < c1.reading . Тоест в този момент ще трябва да увеличите c2.reading с 1 000 000, след което извадете c1.reading . И когато c2.reading >= c1.reading , заявката трябва да изчисли "нормалната" разлика, т.е. да извади c1.reading от оригиналния (неувеличен) c2.reading стойност.

Един от начините да постигнете тази логика е да направите нещо толкова просто като това:

SUM(
  CASE WHEN c2.reading < c1.reading THEN 1000000 ELSE 0 END
  + c2.reading
  - ISNULL(c1.reading, c2.reading)
) AS Count1

Съществува обаче и различен подход.

Вашите стойности на четене и, като следствие, разликите между всеки две от тях, никога не могат да надхвърлят 1 000 000. Следователно можете свободно да прилагате modulo 1 000 000 към положителна разлика и това ще ви върне същата разлика:

d mod 1,000,000 = d

Освен това добавянето на кратни на 1 000 000 към положителна разлика няма да повлияе на резултата от модул 1 000 000, тъй като според разпределимостта на операцията модул,

  (d + 1,000,000 * n) mod 1,000,000 =
= d mod 1,000,000 + (1,000,000 * n) mod 1,000,000

Първото събираемо, d mod 1,000,000 води до d , вторият, (1,000,000 * n) mod 1,000,000 дава 0, d + 0 = d .

От друга страна, добавяне на 1 000 000 към отрицателно разлика ще ни даде правилна положителна разлика.

И така, за да обобщим,

  • добавянето на 1 000 000 към отрицателна разлика ни дава (правилна) положителна разлика,

  • положителна разлика по модул 1 000 000 дава същата положителна разлика и

  • добавянето на 1 000 000 към положителна разлика не влияе на резултата от модул 1 000 000.

Като вземем всичко това предвид, можем да завършим със следния универсален израз за изчисляване на една разлика:

(1000000 + c2.reading - ISNULL(c1.reading, c2.reading)) % 1000000

където % е модулният оператор в Transact- SQL .

Поставете израза в SUM за да получите съответните обобщени стойности:

SUM((c2.reading + 1000000 - ISNULL(c1.reading, c2.reading)) % 1000000) AS Count1



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Милисекунди от DateTime в SQL Server и C# не са еднакви

  2. Върната стойност с помощта на SqlCommand

  3. Вмъкване в таблица от променлива на таблица?

  4. SQL Recursive Query връща само последния ред

  5. Поведение на SQL Server ROW_NUMBER