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

複数のパラメーターと条件でSQLアイランドを検出する

    更新された質問への回答

    SELECT *
    FROM  (
       SELECT *
             ,lag(val, 1, 0) OVER (PARTITION BY status ORDER BY id) last_val
             ,lag(status) OVER (PARTITION BY val ORDER BY id) last_status
       FROM   t1
       ) x
    WHERE  status = 1
    AND    (last_val <> val OR last_status = 0)
    

    どのように?

    以前と同じですが、今回は2つのウィンドウ関数を組み合わせます。デバイスの電源を入れると、..
    1。最後にオンにしたデバイスは異なる 1つ。
    2。または、同じデバイスがオフに切り替えられました その最後のエントリで。 NULLのコーナーケース パーティションの最初の行は無関係です。これは、その行が1ですでに修飾されているためです。

    元のバージョンの質問に対する回答。

    私があなたのタスクを正しく理解している場合、この簡単なクエリが仕事をします:

    SELECT *
    FROM  (
       SELECT *
             ,lag(val, 1, 0) OVER (ORDER BY id) last_on
       FROM   t1
       WHERE  status = 1
       ) x
    WHERE  last_on <> val
    

    要求に応じて行1、3、6、7を返します。

    どのように?

    あなたの説明によると、それは単なるノイズであるため、サブクエリはすべてのスイッチオフを無視します。デバイスの電源がオンになっているエントリを残します。それらの中で、同じデバイスがすでにオンになっている(最後のエントリがオンになっている)場合、それらのエントリのみが失格となります。 ウィンドウ関数lag() そのために。特に私は0を提供します デフォルトでは、最初の行の特殊なケースをカバーします-val = 0のデバイスがないと仮定します 。
    ある場合は、別の不可能な番号を選択します。
    不可能な番号がない場合は、特殊なケースをNULLのままにします。 lag(val) OVER ...を使用 外側のクエリで次のように確認します:

    WHERE last_on IS DISTINCT FROM val
    



    1. クエリプロファイリング101—はい、SQLServerのパフォーマンスを本当に向上させることができます

    2. laravelとpostgresの2つのフィールドを比較する方法

    3. Laravelクエリビルダー-合計するにはどうすればよいですか?

    4. MySqlロジックの最適化