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

連続した日の「ストリーク」の行に実行カウントを追加する方法

    このテーブルに基づいて構築します(SQLキーワード"date"を使用しません 列名として。):

    CREATE TABLE tbl(
      pid int
    , the_date date
    , PRIMARY KEY (pid, the_date)
    );
    

    クエリ:

    SELECT pid, the_date
         , row_number() OVER (PARTITION BY pid, grp ORDER BY the_date) AS in_streak
    FROM  (
       SELECT *
            , the_date - '2000-01-01'::date
            - row_number() OVER (PARTITION BY pid ORDER BY the_date) AS grp
       FROM   tbl
    ) sub
    ORDER  BY pid, the_date;
    

    dateを引く 別のdateから integerを生成します 。連続した日を探しているので、次の行はすべて1つ大きくなります。 。 row_number()を引くと それから、ストリーク全体が同じグループになります(grppidごと 。そうすれば、グループごとの数を簡単に処理できます。

    grp は2つの減算で計算されますが、これが最も速いはずです。同様に高速な代替手段は次のとおりです。

    the_date - row_number() OVER (PARTITION BY pid ORDER BY the_date) * interval '1d' AS grp
    

    1つの乗算、1つの減算。文字列の連結とキャストはより高価です。 EXPLAIN ANALYZEでテストする 。

    pidで分割することを忘れないでください さらに両方 手順を実行しないと、分離する必要のあるグループが誤って混ざってしまいます。

    サブクエリを使用します。これは通常、CTE よりも高速であるためです。 。ここでは、単純なサブクエリで実行できなかったことは何もありません。

    そして、あなたがそれについて言及したので:dense_rank() 明らかにではありません ここで必要です。基本的な row_number() 仕事をします。



    1. 行数を保存しますか、それとも単に行数を数えますか?

    2. SELECT ... WHERE IN(...)を最適化する

    3. mysqlのサブクエリの更新テーブルから列にアクセスする

    4. org.hibernate.MappingException:JDBCタイプの方言マッピングがありません:1111