sql >> データベース >  >> RDS >> Sqlserver

各行の値の差 - 合計エラー

    基本的に必要なのは、一時的に c2.reading のふりをすることです c2.reading < c1.reading の場合のみ、1,000,000 に達した後はラップアラウンドしません .つまり、その時点で c2.reading を増やす必要があります 1,000,000 ずつ、c1.reading を減算します。 . c2.reading >= c1.reading の場合 、クエリは「通常の」差を計算する必要があります。つまり、 c1.reading を減算します 元の (増加していない) c2.reading から

    そのロジックを実現する 1 つの方法は、次のように単純なことを行うことです。

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

    ただし、別のアプローチもあります。

    読み取り値、およびその結果として、それらの 2 つの値の差も 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 になります 、2番目のもの、 (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. Postgresへの接続においてノードは.NETCoreより20倍高速です

    2. エラー:MySQL-データソースをVisual Studioプロジェクトに追加するときに、テーブル'mysql.proc'が存在しません

    3. CentOS 8 /RHEL8にMySQL8.0をインストールする方法

    4. Postgresqlで同等のテーブル値パラメーター