I have a TableA (ID int, [set] int,[status] char(20),
message char(20))
ID set status message
1 1
2 1 MATCH
3 3
4 3 MATCH
5 2
6 2
今私はここで2つのことをしたい:
同じセット内で ‘一致’しない status
= ‘void’
を設定します。したがって、1と3の
ID`は ‘void’を取得します。
xx
は ID
の message = "For ID =
を設定します。それが対応する一致したIDを指し示しているボイドであるメッセージを設定します。
xx"
I also want to NULL the status and message for sets that
do not contain a status of 'Match'
期待される結果:
ID set status message
1 1 VOID For ID = 2
2 1 MATCH NULL
3 3 VOID For ID = 4
4 3 MATCH NULL
5 2 NULL NULL
6 2 NULL NULL
ベストアンサー
最終的解決
私の最初のものとは異なる仮定が、この点を見逃していました。
-
TableA.ID
is unique. - Some rows are marked as ‘MATCH’ to begin with, never
more than one per set. - Mark all other rows of the same set as ‘VOID’ and point to
‘MATCH’ inmessage
. - Set
status
andmessage
to
NULL
for all rows in sets without a ‘MATCH’.
I have prepared a working demo for the new
assumptions you on data.stackexchange.com
- CTEで既成の
メッセージ
を使用して縮小セットを準備します。 - CTEをUPDATEに参加させますが、
[set]
もNULL
にすることができます。 - 明示的な
cast
を使用して整数をcharに変換します。 - 予約語
set
に角括弧を使用します。
予約語を識別子として使用しないことをお勧めします。
最適なパフォーマンスが得られるはずです。
無効な解決策(間違った前提)
-
TableA.ID
is unique - You want the greatest ID per set to be the ‘MATCH’ and
all others to be ‘VOID’, regardless of the pre-UPDATE state of
status
andmessage
.
UPDATE TableA
SET status = CASE ID WHEN x.max_id THEN 'MATCH' ELSE 'VOID' END
,message = CASE ID WHEN x.max_id THEN NULL
ELSE 'FOR ID = ' + CAST (x.max_id AS char) END
FROM (
SELECT [set]
,max(ID) AS max_id
FROM TableA
GROUP BY [set]
) AS x
WHERE x.[set] = TableA.[set]