0

次のスキーマがあります。

id | order_ref | description | price

現在、次の重複した問題があります。

1 | 34567 | This is the description | 19.99
2 | 34567 | This is the description | 13.99

これは、インポートしたデータに各項目の説明が重複していたためです。最初の行を保持し、その後 (最大約 20 行) の説明を「AS ABOVE」に更新する方法はありますか?

1 | 34567 | This is the description | 19.99
2 | 34567 | - AS ABOVE - | 13.99

ありがとう

- - - -更新しました

UPDATE documents_orders_breakdown
SET `desc` = '- AS ABOVE -'
WHERE NOT id IN (SELECT id
             FROM documents_orders_breakdown AS D
             WHERE D.`desc` <> `desc`
             ORDER BY D.id
             LIMIT 1)

しかし、これは [Err] 1235 を返します - このバージョンの MySQL はまだ「LIMIT & IN/ALL/ANY/SOME subquery」をサポートしていません

- - - - 更新しました

UPDATE documents_orders_breakdown
SET `desc` = '- AS ABOVE -'
WHERE NOT id IN (SELECT MIN(id)
                 FROM documents_orders_breakdown AS t
                 WHERE t.`desc` = `desc`)

これは [Err] 1093 を返すようになりました - FROM 句で更新するターゲット テーブル 'documents_orders_breakdown' を指定できません

4

3 に答える 3

1

これが 1 回限りのことであれば、パフォーマンスは大きな問題ではありません。LIMIT が 1 の SELECT で返されないすべてのレコードに対して UPDATE を実行できます。

UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT id
                 FROM the_table t
                 WHERE t.description = the_table.description
                 ORDER BY t.id
                 LIMIT 1)

このクエリは、ID が最初に来るレコードの説明を保持することを前提としています (したがって、ORDER BY です)。


サブクエリでは LIMIT を使用できないため、集計関数 MIN を使用して回避できます。

UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT MIN(id)
                 FROM the_table t
                 WHERE t.description = the_table.description)

(MINとサブクエリを混在できることを願っています;)


MySQLで UPDATE しているテーブルから SELECT できないようです。回避策は、暗黙的な一時テーブルを使用することです。これはパフォーマンスには悪いですが、繰り返しになりますが、これは 1 回限りのことであり、大きな懸念事項ではありません。

UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT m FROM (SELECT MIN(id) AS m
                 FROM the_table t
                 WHERE t.description = the_table.description) AS temp)
于 2011-06-27T09:09:07.673 に答える
0

行の順序付け (または順序付けの欠如) について Oswald が行ったコメントは非常に重要です。このテーブルから選択されたソートされていない行が期待どおりの順序になるという保証はありません。これは、テーブル内の既存の順序を毎回指定しない限り、現実を反映していない場合でも「AS ABOVE」とタグ付けされる可能性があることを意味します。さらに、これまでに提供されたソリューションのいずれも、順不同のレコードを適切に処理しません。
全体として、これはクエリの問題というよりも、データベースの設計の問題 (具体的には正規化の問題) のように思えます。
理想的には、説明は (必要な ID とともに) いくつかのマスター データ テーブルに抽出されます。次に、使用する説明に関する選択は、'SELECT' の実行時に任されます。これには、順序の変更に対して「AS ABOVE」を安全にするという追加の利点があります。

したがって、order_ref 列の各インスタンスに異なる説明 (「AS ABOVE」ビットを除く) が必要であると仮定すると、テーブルは次のようにリファクタリングできます。

id | order_ref | price 
======================= 
 1 | 34567     | 19.99  
 2 | 34567     | 13.99  

order_ref_fk | description  
==========================================
34567        | "This is the description"

この時点で、通常どおり説明テーブルに参加します。異なる説明を表示することは、通常は表示の問題であり、表示する行を出力しているプログラムによって処理されます (データベースに直接ではありません)。

これをデータベース内で行うことを主張する場合は、次のように書くことができますSELECT

SELECT Orders.id, Orders.order_ref, Orders.price,
       COALESCE(Dsc.description, 'AS ABOVE')
FROM Orders
LEFT JOIN (Description
           JOIN (SELECT order_ref, MIN(id) AS id
                 FROM Orders
                 GROUP BY order_ref) Ord
             ON Ord.order_ref = Description.order_ref_fk) Dsc
        ON Dsc.order_ref_fk = Orders.order_ref
           AND Dsc.id = Orders.id
ORDER BY Orders.order_ref, Orders.id
于 2011-06-27T22:38:03.100 に答える
0

リレーショナル データベースには、後続の概念がありません。テーブル内のレコードは特定の順序ではありません。クエリで順序を指定しない場合、予期しない順序でSELECTレコードが取得されると想定する必要があります。

于 2011-06-27T09:08:35.320 に答える