web-dev-qa-db-ja.com

行内の他の値に基づく日時値で列全体を更新する

次のロジックに従って、非常に大きなテーブル[server]。[dbo]。[MyTable]があり、列 'ToDateTime'(現在はNULLでいっぱい)を埋めるSQLステートメントが必要です。

  • AIDが123、PIDが2の行(下の行2、4、5、7)の「ToDateTime」にのみ値を追加します。それ以外の場合は、「ToDateTime」をNULLのままにします。

  • 上記の条件が満たされ、データ(varchar)を日時に変換できない場合は、 'ToDateTime'をNULLに設定/残す(以下の行5および7には日時変換に失敗するデータがあります)

  • ただし、datetimeに変換できる値(行2および4)が含まれている場合は、値を変換し、その変換された値でToDateTimeの値を更新します。

前:

ID | AID | PID | ContainedData        | ToDateTime
_________________________________________________
1  | 123 |  1  | xxxx                 | NULL
2  | 123 |  2  | 7/21/2015 8:15:06 AM | NULL
3  | 234 |  2  | xyxy                 | NULL
4  | 123 |  2  | 19/07/2015 12:29:42  | NULL
5  | 123 |  2  | NULL                 | NULL
6  | 345 |  3  | zzzz                 | NULL
7  | 123 |  2  | badTimeString        | NULL

後:

ID | AID | PID | ContainedData        | ToDateTime
_________________________________________________
1  | 123 |  1  | xxxx                 | NULL
2  | 123 |  2  | 7/21/2015 8:15:06 AM | 2015-07-21 08:15:06.000
3  | 234 |  2  | xyxy                 | NULL
4  | 123 |  2  | 19/07/2015 12:29:42  | 2015-07-19 12:29:42.000
5  | 123 |  2  | NULL                 | NULL
6  | 345 |  3  | zzzz                 | NULL
7  | 123 |  2  | badTimeString        | NULL

以下に似たクエリを試しましたが、ToDateTimeにすべての行の同じ値が入力されています(実際のデータの場合はNULL)。このクエリに似たものが適切なアプローチかどうかはわかりません、または私が道を外れている場合。

UPDATE MyTable SET ToDateTime =
CASE
WHEN ISDATE(myT.cd)= 1 
THEN CONVERT(DATETIME, myT.cd)
ELSE NULL END
FROM (
 SELECT ContainedData cd
 FROM MyTable
 WHERE [AID] = 123 AND [PID] = 2
 ) myT
2
Krondorian

少なくとも2つの異なる地域の日付形式(おそらく米国とヨーロッパ)があるようです。更新を言語ごとに分割することもできます...

このようなもので、言語設定を使用してisdateと変換を制御します。

set language english;
update test_dates 
set ToDateTime = convert(datetime,ContainedData)
where AID='123' and PID='2' and isdate(ContainedData)=1;

set language british;
update test_dates 
set ToDateTime = convert(datetime,ContainedData)
where AID='123' and PID='2' and isdate(ContainedData)=1;

テーブルが大きすぎて大きなチャンクで更新できない場合は、行の制限と更新ごとのトランザクションを含むループでそれをラップして、行が更新されなくなるまで繰り返す必要があります。

2
Mister Magoo

これはどう:

UPDATE [dbo].[MyTable]
SET [ToDateTime] = [ContainedData]
WHERE aid = 123 
and pid = 2 
and isdate([ContainedData] ) = 1
2
DThompson