2012-01-04 15 views
0

にはmeterreadingsというテーブルがあります。ある行から別の行に属性meterreadingをコピーする必要があります。ここでこのMySQLアップデートはなぜ動作しませんか?

は、データのサンプルです:

id   |  meterreadingdate  |  meterreading  |  meterreadingtype_id | created 
------------------------------------------------------------------------------- 
1    |  2011-10-01        |  0             |  1                   | 2011-10-15 
2    |  2011-10-01        |  500           |  2                   | 2011-10-15 

だから基本的に、私は2のmeterreadingtype_id値は1

に上書きコピーするように meterreadingtype_id列に基づいて meterreadingすべての値をコピーしたいです完了したら

データは次のようになります。私は理由上で500をコピーし

id   |  meterreadingdate  |  meterreading  |  meterreadingtype_id | created 
------------------------------------------------------------------------------- 
1    |  2011-10-01        |  500           |  1                   | 2011-10-15 
2    |  2011-10-01        |  500           |  2                   | 2011-10-15 

お知らせは1であり、それはここで2

だったので、私は次の行から値を行く私が使用していますクエリです:

update meterreadings mr1 
set meterreading =  
(
    select 
     meterreading  
    from meterreadings 
    where 
     meterreadingtype_id = 2 
     and meterreadingdate = mr1.meterreadingdate 
     and location_id = mr1.location_id 
     and created = mr1.created 
     and asset_id = mr1.asset_id 
) 
where asset_id in (select id from assets where model_id in (select id from models where make_id IN (81, 82))) 
and meterreadingtype_id = 1 

我々は、MySQL 5とInnoDBテーブルを使用している場合に役立ちます。

+0

申し訳ありません、掲示に問題があります。企業のファイアウォールが実際の更新ステートメントをブロックしています。 – cbmeeks

+0

エラーが発生するか、または0行が更新されますか? –

+0

@Michael編集をありがとう。 Corpのファイアウォールが更新ステートメントの投稿をブロックしていました。 – cbmeeks

答えて

1

テーブルを変更してサブクエリ内の同じテーブルから選択できないため、クエリが失敗しています。 SET、DELETE、SELECT、INSERT、UPDATE、またはDO:

を参照してくださいSubquery Syntax

一つの制限は、サブクエリの外側のステートメントのいずれかでなければならないということです。もう1つの制約は、現時点では、テーブルを変更したりサブクエリ内の同じテーブルから選択することができないことです。これは、DELETE、INSERT、REPLACE、UPDATE、および(SET句でサブクエリを使用できるため)LOAD DATA INFILEなどの文に適用されます。私は、MySQLの専門家だが、私はMySQLは最初のサブクエリを処理してメモリに結果を格納するため、この作品信じる

UPDATE meterreadings AS tgt 
INNER JOIN (
    SELECT * FROM meterreadings 
    WHERE meterreadingtype_id = 2 
) AS src 
ON tgt.meterreadingdate = src.meterreadingdate 
    AND tgt.location_id = src.location_id 
    AND tgt.created = src.created 
    AND tgt.asset_id = src.asset_id 
SET tgt.meterreading = src.meterreading 

私はあなたには、いくつかでこの問題を回避することができると思うが策略を登録しようUPDATE中に変更されない一時テーブル。これの副作用は、サブクエリの結果が大きい場合、メモリのトンを掘り下げる(または使い果たしてしまう)ということです。

メモリの問題を回避する唯一の方法(私が知る限り)は、更新ターゲットに直接関連しない基準を使用してサブクエリを削除することです。たとえば、夜間処理の一環としてこれらの更新を行う場合、内部SELECTは過去24時間以内に作成された行のみを返すようにします。

+0

ええ、それは私が得ているものです。より良い方法がありますか? – cbmeeks

+0

@cbmeeks:更新された回答を参照してください。 –

+0

私は実際にはもっと簡単な方法を見つけましたが、私はあなたに答えを与えました。私が実際にしたことは、すべての1を削除してから、2を1に変更しました。笑。同じことをしたか – cbmeeks

関連する問題