2

テーブル内の識別可能な各レコードごとに最小 5 レコードのみを保持する SQL を作成する必要があります。このために、partition by返された値が 5 より大きいすべてのレコードを使用して削除します。partition byステートメントと同じクエリで WHERE 句を使用しようとすると、「順序付き分析関数は WHERE 句では許可されていません」というエラーが表示されます。したがって、それを機能させるには、3 つのサブクエリを使用する必要があります。私のSQLはこれと同じように見えます:

delete mydb.mytable where (field1,field2) in
(
    select field1,field2 from
    (
        select field1,field2,
        Rank() over
        (
            partition BY field1
            order by field1,field2
        ) n 
        from mydb.mytable
    ) x
    where n > 5
)

最も内側のサブクエリは生データを返すだけです。そこでは WHERE を使用できないため、サブクエリでラップしました。その目的は、1) WHERE を使用してランクが 5 を超えるレコードを取得し、2) フィールド 1 とフィールド 2 のみを選択することです。これら 2 つのフィールドのみを選択する理由は、最も外側のクエリでこれらのレコードを削除するために IN ステートメントを使用できるようにするためです。

動作しますが、少し面倒です。内側の 2 つのサブクエリを 1 つのサブクエリに統合したいと考えています。これは可能ですか?

4

1 に答える 1

1

Window Aggregate 関数QUALIFYの句である句を使用する必要があるようです。HAVING以下は、あなたが達成しようとしていることに対する私の見解です。

最初にテストせずに、本番データに対してこの SQL を直接実行しないでください。

/* Physical Delete */
DELETE TGT
  FROM MyDB.MyTable TGT
 INNER JOIN
       (SELECT Field1
             , Field2
        FROM MyDB.MyTable
        QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
              > 5
       ) SRC
    ON TGT.Field1 = SRC.Field1
   AND TGT.Field2 = SRC.Fileld2

/* Logical Delete */
UPDATE TGT
  FROM MyDB.MyTable TGT
     ,
       (SELECT Field1
             , Field2
        FROM MyDB.MyTable
        QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
              > 5
       ) SRC
   SET Deleted = 'Y'
    /* RecordExpireDate = Date - 1 */
 WHERE TGT.Field1 = SRC.Field1
   AND TGT.Field2 = SRC.Fileld2
于 2012-12-06T19:25:35.410 に答える