2017-03-08 5 views
0

SQLサーバーの1対多の関係のJOINのは、私​​は、クエリにUPDATEは

UPDATE A 
SET Col2 = B.Col2 
FROM A 
INNER JOIN B ON A.Col1 = B.Col1 
を以下している場合は、私はテーブル

Col1 Col2 
1 AB 
2 CD 

B

Col1 Col2 
1 EF 
1 GH 
2 IJ 
2 KL 

を持っているとしましょう

これを試したところ、結果は次のとおりです

Col1 Col2 
1 EF 
2 IJ 

だから、それは常に最初の行から更新?ちょうど私が更新しようとしていることは非常に重要なので、正しい動作を確認したかったのです。

+1

いいえ自然な「最初の行」があることを理解することが重要です。最初の行を指定するには、必ず 'ORDER BY'を指定する必要があります。ランダムな行から更新されます。 (この場合、多くの場合、最初に認識する行です)更新ソースとして使用されるものを確実に確認するには、最初の行を特定してフィルタリングするソースから更新する必要があります。このような「注文のない最初の行」の考え方に基づいてビジネスロジックを構築すると、バグが発生します。 –

答えて

1

RDBMSのテーブルについて話すときに、「最初の行」または「最後の行」というような定義はありません。順序を指定していない場合、データベースエンジンは任意のレコードをFirst Recordとして自由に使用できます。もちろん、クラスター化されたインデックスや照合などの例外もあります。

注文を指定しない場合は、最初のレコードの内容を単純に仮定することはできません。

更新プログラムで必要な値の定義済みの順序を使用するようにクエリを変更することをお勧めします。例えば。あなたはアルファベット順に最初に来た値に更新したい場合は、このクエリを使用します。

UPDATE A 
SET Col2 = B.Col2 
FROM A 
INNER JOIN 
(
SELECT Col1, Col2, 
ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2) rn 
) 
B ON A.Col1 = B.Col1 AND b.rn=1 

あなたが順序を指定するときに順番が完全に異なる列が設定できることに注意してください。 DateUpdated列があり、最新のDateUpdatedイベントに基づいて最新の値を使用するとします。

UPDATE A 
SET Col2 = B.Col2 
FROM A 
INNER JOIN 
(
SELECT Col1, Col2, DateUpdated, 
ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY DateUpdated DESC) rn 
) 
B ON A.Col1 = B.Col1 AND b.rn=1