2

私は2つのテーブルを持っています

テーブル名:Attributes

attribute_id  |   attribute_name

    1               attr_name_1
    2               attr_name_2
    3               attr_name_1
    4               attr_name_2

テーブル名:Products

product_id    |   product_name    |    attribute_id
    1              prod_name_1              1
    2              prod_name_2              2
    3              prod_name_3              3
    4              prod_name_4              4

ご覧attribute_idのとおり、表には の代わりにProducts次の ID があります。(1,2,3,4)(1,2,1,2)

問題は tableにあります。つまり、異なる ID を持つAttributes繰り返し値 ( ) があるため、次のようにします。attribute_names

  1. テーブルから、繰り返しの 1 つの ID を選択するにはAttributes
  2. Productsその「選択された」 IDでテーブルを更新します(attribute_idテーブルに同じ名前がある場合のみAttributes
  3. その後、繰り返し値をテーブルから削除しますAttributes魔女はテーブルで使用されませんProducts

出力:

テーブル名:Attributes

attribute_id  |   attribute_name
     1              attr_name_1
     2              attr_name_2

テーブル名:Products

product_id    |   product_name    |    attribute_id
     1             prod_name_1              1
     2             prod_name_2              2
     3             prod_name_3              1
     4             prod_name_4              2

SQLFiddleデモ

ノート:

この問題を手動で修正する代わりにSQLを使用すると、非常に役立ちます。

4

2 に答える 2

1

以下は@Alexander Sigachovの提案よりも速いかもしれませんが、それを実行するには少なくともSQL Server 2005が必要ですが、AlexanderのソリューションはSQL Serverの(合理的な)バージョンで動作します. それでも、代替手段を提供するためだけに、ここに行きます:

WITH Min_IDs AS (
  SELECT
    attribute_id,
    min_attribute_id = MIN(attribute_id) OVER (PARTITION BY attribute_name)
  FROM Attributes
)
UPDATE p
SET    p.attribute_id = a.min_attribute_id
FROM   Products p
JOIN   Min_IDs  a ON a.attribute_id = p.attribute_id
WHERE  a.attribute_id <> a.min_attribute_id
;

DELETE FROM Attributes
WHERE attribute_id NOT IN (
  SELECT attribute_id
  FROM   Products
  WHERE  attribute_id IS NOT NULL
)
;

最初のステートメントのCTEは、 every が同じattribute_idの最小値にマップされる行セットを返します。このマッピング セットに結合することにより、ステートメントはそれを使用してテーブル内の sを置き換えます。attribute_idattribute_nameUPDATEattribute_idProducts

後で から削除するときは、列に が見つからないAttributesかどうかを確認するだけで十分です。これは、2 番目のステートメントが行うことです。つまり、他の回答のように、グループ化と集約はこの時点では必要ありません。Attributes.attribute_idProducts.attribute_id

WHERE attribute_id IS NOT NULL列が NULL 可能で、実際に NULL を含む可能性がある場合、条件は 2 番目のクエリのサブクエリに追加されます。この場合、NULL を除外する必要があります。そうしないと、NULL が存在するとNOT IN述語が に評価されUNKNOWN、SQL Server はこれを と同じように扱いますFALSE(したがって行は実質的に削除されません)。に NULL が存在できない場合Products.attribute_id、条件はドロップされる可能性があります。

于 2013-06-19T06:36:34.580 に答える