18

私の目標は、グループ化されたCaseKeyのMAX(recordDate)ではないすべてのレコードをテーブルから削除することです。したがって、3つのケースキーの3つのセットを持つ9つのレコードがあり、各ケースキーには3つの日付があります。各セットの下位2つの日付を削除して、合計3つのレコードを作成し、それぞれのMAX(recordDate)のみを残します。

私は次のSQLクエリを持っています:

    DELETE FROM table
    WHERE tableID NOT IN (
    SELECT tableID
    FROM (
    Select MAX(recordDate) As myDate, tableID From table
    Group By CaseKey
    ) As foo
    )

エラーが表示されます:3行目のエラー...列'table.tableID'は、集計関数またはGROUP BY句のいずれにも含まれていないため、選択リストでは無効です。

明らかに、group By句にtableIDを追加することはできますが、そのステートメントの結果は正しくなく、グループ化されたCaseKeysのMAX recordDateを返すだけでなく、すべての行を返します。

サーバーは現在ダウンしていますが、明らかな答えは次のとおりです:(WildPlasserの答えからの小さな調整)

DELETE zt FROM ztable zt
WHERE EXISTS (
    SELECT * FROM ztable ex
    WHERE ex.CaseKey = zt.CaseKey
    AND ex.recordDate > zt.recordDate
);

つまり、ztのレコードごとにクエリを実行して、同じレコードにrecordDateが高いレコードも含まれているかどうかを確認します。その場合、WHERE EXISTSステートメントは合格し、レコードは削除されます。そうでない場合、WHEREステートメントは失敗し、レコードはそれ自体のMAXrecordDateになります。

WildPlasser、私がどういうわけか爆破していたその単純な方法論に感謝します。

4

3 に答える 3

24

MAX には特別なプロパティが 1 つあります。max よりも高い値を持つレコードはありません。したがって、CaseKey が同じで、recordDate が大きいレコードが存在するすべてのレコードを削除できます。

DELETE FROM ztable zt
WHERE EXISTS (
    SELECT *
    FROM ztable ex
    WHERE ex.CaseKey = zt.CaseKey
    AND ex.recordDate > zt.recordDate
    );

ところで: 上記のクエリ (およびMAX()バージョン) は、最大の日付を持つレコードが 1 つしかないことを前提としています。縁もあるでしょう。

同数の場合は、where 句に追加のフィールドを追加する必要があります。タイブレーカーとして。それがそのように機能すると仮定するとTableId、クエリは次のようになります。

DELETE FROM ztable zt
WHERE EXISTS (
    SELECT *
    FROM ztable ex
    WHERE ex.CaseKey = zt.CaseKey
    AND (   ex.recordDate > zt.recordDate
        OR (ex.recordDate = zt.recordDate AND ex.TableId > zt.TableId)
        )
    );
于 2013-01-10T19:13:53.353 に答える
6

表現するだけ

グループ化された CaseKey の MAX(recordDate) ではないすべてのレコードをテーブルから削除します

としてSQLで

DELETE FROM table t1
WHERE t1.recordDate <> 
  (SELECT MAX(recordDate)
   FROM table t2
   WHERE t2.CaseKey = t1.CaseKey)
于 2013-01-10T21:26:26.560 に答える
1

ランク > 1 ですべてのレコードをランクcaseKey​​付けして、より低い日付のみを返すことができます。そうすれtableID.

DELETE FROM [table]
WHERE [tableID] IN
  (SELECT
    [sub].[tableID]
  FROM
  (
    SELECT 
      [tableID],
      Rank() OVER (PARTITION BY [caseKey] ORDER BY [recordDate] DESC, [tableID] DESC) AS [rank]
    FROM [table]
  ) AS [sub]
  WHERE [sub].[rank] > 1)
于 2013-01-10T20:19:34.500 に答える