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

特定の基準を満たす連続した日のグループを作成する

    この回答では、例のデータのように、日付の昇順で並べ替えると、「id」フィールドが行に連続して番号を付けると仮定します。 (そのような列が存在しない場合は作成できます)。

    これは、こちら で説明されている手法の例です。 こちら .

    1) 隣接する「id」値でテーブルを結合します。これにより、隣接する行がペアになります。 「割り当て」フィールドが変更された行を選択します。結果を一時テーブルに保存し、実行中のインデックスも保持します。

    SET @idx =0;CREATE TEMPORARY TABLE boundsSELECT (@idx :=@idx + 1) AS idx, a1.date AS prev_end, a2.date AS next_start, a1.allocation as allocationFROM 割り当て a1JOIN 割り当て a2ON (a2.id =a1.id + 1)WHERE a1.allocation !=a2.allocation;  

    これにより、各行に「前の期間の終わり」、「次の期間の開始」、および「前の期間の「割り当て」の値」を含むテーブルが得られます。

    <前>+------+------------+------------+---------- --+| idx |前へ | next_start |割り当て |+------+------------+------------+------------+| 1 | 2012-01-01 | 2012-01-02 | 0 || 2 | 2012-01-02 | 2012-01-03 | 2 || 3 | 2012-01-05 | 2012-01-06 | 0 |+-----+------------+------------+------------+

    2) 各ピリオドの開始と終了が同じ行にある必要があるため、隣接する行を再度結合する必要があります。 boundaries のような 2 番目の一時テーブルを作成してこれを行います しかし idx を持っています フィールド 1 より大きい:

    <前>+------+------------+------------+| idx |前へ | next_start |+--------------------+------------+------------+| 2 | 2012-01-01 | 2012-01-02 || 3 | 2012-01-02 | 2012-01-03 || 4 | 2012-01-05 | 2012-01-06 |+------+------------+------------+

    idx に参加しましょう フィールドに入力すると、答えが得られます:

    SELECT 境界 2.next_start AS 開始、boundary.prev_end AS 終了、allocationFROM 境界結合境界 2USING(idx);+------------+---------- --+------------+|開始 |終了 |割り当て |+------------+------------+------------+| 2012-01-02 | 2012-01-02 | 2 || 2012-01-03 | 2012-01-05 | 0 |+------------+------------+------------+  

    ** この回答は「内部」期間を正しく取得しますが、最初に割り当て =0、最後に割り当て =5 である 2 つの「エッジ」期間を見逃していることに注意してください。これらは UNION を使用して取り込むことができます 節はありませんが、複雑にすることなく核となるアイデアを提示したかったのです。



    1. Oracleデータベースの複数のフィールドを持つ条件付き一意制約

    2. UNPIVOT で NULL 値を処理する

    3. Mysqlトランザクション:コミットとロールバック

    4. Digital Ocean Postgresマネージドデータベースに接続するために、SSL証明書(ca-cert)をnode.js環境変数に追加するにはどうすればよいですか?