web-dev-qa-db-ja.com

重複を1つだけ選択する

私は注文書とストックルームのチェックアウトのデータベースを持っています。ストックルームのチェックアウトは重複して挿入される傾向があるようです(このデータは古いシステムから毎晩提供されています)。このテーブルからすべての行を取得するための選択は何ですか?一度に1つの重複のみを選択しますか?約10万の複製があり、私のDB担当者はまだクリスマス休暇中です:|

テーブルには一意のキーがありますが、キー以外のデータは数千回複製されます。データを削除しないようにしたい(念のため)。サーバーはMSSQL2012を実行しています。デスクに戻ったら、この投稿をテーブル構造で編集します。

3
Johnley

返される行を他の列の集計ではなく、完全な完全な行にする場合は、CTEを使用できます。 ORDER BYは、任意の列で行を優先します(グループ化は、一意であると思われるものによる)。

;WITH x AS
(
  SELECT col1, col2, col3, 
    rn = ROW_NUMBER() OVER 
    (
        PARTITION BY unique_columns 
        ORDER BY unique_columns, tie_breaker_if_you_care
    )
  FROM dbo.source_table
)
SELECT col1, col2, col3 FROM x WHERE rn = 1;
10
Aaron Bertrand

JacoのDISTINCTの使用に関する提案は、多くの場合に機能します。

「重複」間で異なる可能性のあるフィールドに関する情報が必要な場合は、代わりに同一のアイテムをグループ化して、残りで集計を使用できます。

_SELECT field1, field2
     , COUNT(*) AS NumberOfCopies
     , MIN(some_numeric_or_date_field_that_varies) AS minValue
     , MAX(some_numeric_or_date_field_that_varies) AS maxValue
GROUP BY field1, field2
_

最初または最後の重複に関する特定の情報が必要な場合は、ウィンドウ関数(particularly ROW_NUMBER())を使用することもできますが、少し複雑になります。データに関する詳細を質問に追加できる場合は、関連があると思われる場合に、より具体的な例を提供できます。

2
David Spillett

DISTINCTを使用できますが、タイムスタンプなど、重複する2つの行で異なる可能性がある列は必ず省略してください。

SELECT DISTINCT Field1, Field2
FROM dbo.Table

または、注文IDや請求書番号など、自然キーの一部であるフィールドでグループ化することもできます。

SELECT order_id, 
       MAX(total_order_value) AS total_order_value, 
       MAX(number_of_items) AS number_of_items, 
       MAX(price_per_item) AS price_per_item,
FROM dbo.Table
GROUP BY order_id
1
Alex