2016-08-05 13 views
1

私は自分の仕事で問題が発生しました。私は間違ってレコードをたくさん更新しました。だから、それを元に戻すために、私はthis questionに続き、修正日の降順に従ってテーブルのすべてのレコードを注文し、2番目の最後のレコードを得ました。これは私の誤った更新前の値を示しました。だから私は、レコードを更新するには、このような何かを書いた:2つのWHERE句に値の範囲を入れてください

update table1 set col1 = (select top 1 col1 from 
    (select top 2 * from table1 where col2 = val1 order by dateofmodification desc) X 
    order by dateofmodification 
where col2 = val1 

それはうまく動作しますが、ここで問題です。私は、更新するレコードを一揃い、つまり、col2が一致する値の全体、つまりval1, val2, val3, .....を持っています。どのようにサーバーをSQLになるので

update table1 set col1 = (select top 1 col1 from 
    (select top 2 * from table1 where col2 in (val1, val2, val3) order by dateofmodification desc) X 
    order by dateofmodification 
where col2 in (val1,val2, val3) 

VAL1は2つのWHERE句でVAL1に一致させる知っている:私はので、そうのような2つのWHERE句の値の範囲内に置くことができませんか?

ここで何をすればいいですか?

編集:ここでは、サンプル表

Employees 

name | emp_id | address | department | dateofmodification 

私がミスを犯し、従業員レコードの束を更新し、いくつかのランダムなジャンクに自分の部門を台無しです。

私はこのクエリ

update Employees set department = (select top 1 department from 
    (select top 2 * from Employees where address = 'Chicago' order by dateofmodification desc) X 
where address = 'Chicago' 

を実行するのであれば、それはうまく動作しますが、都市だけでなく、シカゴの全体の束があります。私はそれらの値を一つずつ差し込みたくない。

+0

SOユーザーに不必要な頭痛を与えないようにするには、問題を示すサンプルテーブルを表示できますか? –

+0

サンプルテーブルを追加しました。希望が役立ちます。 –

答えて

1

更新はタプルを使用することができます - このように:

update tablename 
set (f1, f2, f3, f4) = (select a1, a2, a3, a4 from another_tablename) 

プラットフォームがタプル(私はあなたを見てるのSQL Server)をサポートしていない場合、それは

update tablename 
    set f1=a1, f2=a2, f3=a3, f4=a4 
    FROM another_tablename 
ように書き換えることができます

コメントに基づいて更新します。

ありませんが、あなたがこの

更新従業員は

set department = 
    (select top 1 department from 
     (select top 2 * 
     from Employees 
     where address in ('Chicago', 'New York', 'Dallas', 'Miami') 
     order by dateofmodification desc 
     ) X   
    order by dateofmodification asc 
    ) 

は、あなたがこのようにそれをやったときにすることにより2次を必要とする方法を見たいですか?


コースのSQL Serverの

最良の方法は、OracleとDB2がそうであるようにフェッチおよびオフセットをサポートしています。

set department = 
    select department 
    from Employees 
    where address in ('Chicago', 'New York', 'Dallas', 'Miami') 
    order by dateofmodification asc 
    offset 1 row 
    fetch first 1 row only 

CF http://sqlmag.com/sql-server-2012/using-new-offset-and-fetch-next-options

+0

だから、もし私が ''更新する従業員の部署=(( 'シカゴ'、 'ニューヨーク'、 'ダラス'、 'マイアミ')のアドレスを持つ従業員から (トップ2部門を選択してトップ1部門を選択すると、dateofmodification desc )X 住所は( 'シカゴ'、 'ニューヨーク'、 'ダラス'、 'マイアミ') 'それはそれに応じて更新されますか? –

+0

@SidharthSamant - オフセットを取得し、最初に取得する - 私の編集を参照してください。 – Hogan

+1

あなたの質問表示されているように、更新ステートメントでタプルを使用することはサポートしていません。 –

0

は、第二の最新の変更とあなたの問題の一部がホーガンの答えに対処された取得するためのさまざまな方法があります。しかし、複数のアドレスにまたがってアップデートを実行する方法も探していると思います。

あなたがしなければならないことは、inで試したものではなく、内側のクエリを相関させることです。これは、すべての値に対して繰り返すのではなく、クエリ全体を1回だけ実行できるようにする必要があります。

update Employees 
set department = (
    select top 1 department from (
     select top 2 * from Employees 
     where address = Employees.address -- <-- correlated here 
     order by dateofmodification desc 
    ) e2 
    order by dateofmodification 
) 
where address in ('Chicago', ...) 
関連する問題