2012-04-11 8 views
0

私は次のことを経験しています、なぜ誰もが説明することができ、私は、それを失っていると思う: ここには私のクエリです:更新(参加)

update financials.operator_summary_daily set 
     osm_fos_id = fos_id 
    from financials.operator_summary_daily daily 
    join (
     select 
      osm_id, 
      fos_id 
     from financials.operator_summary_daily daily 
     join financials.operator_settlement_monthly on daily.osm_opt_id = fos_opt_id and date_trunc('month', daily.osm_timestamp)::timestamp = date_trunc('month', fos_timestamp)::timestamp --and daily.osm_fos_id is null 
    ) as result on result.osm_id = daily.osm_id 

内側のクエリでは、1963年のレコードを返しますが、更新financials.operator_summary_dailyのテーブル全体で実行され、すべての39Kレコードが更新されます。

私はここで何が欠けていますか?

テーブル:

CREATE TABLE financials.operator_summary_daily 
(
    osm_id bigint NOT NULL DEFAULT nextval('financials.operator_summary_monthly_osm_id_seq'::regclass), 
    osm_timestamp timestamp without time zone NOT NULL, 
    osm_opt_id bigint NOT NULL, 
    osm_gam_id bigint NOT NULL, 
    osm_cur_id bigint NOT NULL, 
    osm_ctt_id bigint NOT NULL, 
    osm_turnover double precision NOT NULL, 
    osm_revenue double precision NOT NULL, 
    osm_timestamp_created timestamp without time zone NOT NULL DEFAULT now(), 
    osm_timestamp_updated timestamp without time zone NOT NULL DEFAULT ('now'::text)::date, 
    osm_fos_id bigint 
); 


CREATE TABLE financials.operator_settlement_monthly 
(
    fos_id bigserial NOT NULL, 
    fos_timestamp timestamp without time zone NOT NULL, -- Monthly timestamp 
    fos_opt_id bigint NOT NULL, 
    fos_royalties double precision NOT NULL, 
    fos_carry_over double precision NOT NULL, 
    fos_other_adjustments double precision NOT NULL, 
    fos_due double precision NOT NULL, 
    fos_collectable double precision NOT NULL, 
    fos_balance double precision NOT NULL, 
    fos_collected double precision NOT NULL, 
    fos_baddebt double precision NOT NULL, 
    fos_carryforward double precision NOT NULL, 
    fos_ses_id bigint NOT NULL, 
    fos_timestamp_created timestamp without time zone NOT NULL DEFAULT now(), 
    fos_datetime_updated timestamp without time zone NOT NULL DEFAULT now(), 
    fos_prq_id bigint 
); 

EDIT:
は参加条件が残っていない、しかし、どこの必要性があってはならない、あなたの迅速な回答をいただきありがとうございます、それは包括的だとだけレンダリングする必要があります更新のための一致した行。したがって、37Kのうち1963個のレコード(結合基準を満たすもの)のみを更新する必要があります。私が間違っている?

ANSWER: 正しいスクリプト:

UPDATE financials.operator_summary_daily d 
    SET osm_fos_id = m.fos_id 
    FROM financials.operator_settlement_monthly m 
    WHERE 
     m.fos_opt_id = d.osm_opt_id 
     AND date_trunc('month', d.osm_timestamp) = date_trunc('month', m.fos_timestamp) 
     AND d.osm_fos_id is null; 

@ErwinBrandstetterありがとうございます。 どうやら、私はJOINの間違った仮定を使用していました、私の背景はMS-SQLであり、別のところで動作します。 エンドエンドのソリューションを見て、JOINは完全に削除され、T-SQLでは実行できないセカンダリテーブルへの直接呼び出しと交換されました。

ところで、次のように動作せず、他のコメントのようにwhere句が含まれています。私はまだレコードを更新するときにJOINに関してpgsqlがどのように動作するかに関して困惑しています。複雑な参加

update financials.operator_summary_daily set 
     osm_fos_id = fos_id 
    from financials.operator_summary_daily daily 
    join (
     select 
      osm_id, 
      fos_id 
     from financials.operator_summary_daily daily 
     join financials.operator_settlement_monthly on daily.osm_opt_id = fos_opt_id and date_trunc('month', daily.osm_timestamp)::timestamp = date_trunc('month', fos_timestamp)::timestamp 
    ) as result on result.osm_id = daily.osm_id 
    where 
     daily.osm_id = result.osm_id 
     and daily.osm_fos_id is null; 
  • は、内側のクエリは、「デバッグ」の目的のためにテーブル全体のサブセットのみを返すことを確認しようとしてくれた結果です。

もう一度おねがいします!

答えて

1

更新の条件はありません。WHERE

この文は、all行を更新します。

あなたの文は次のように(単純化された多くを)うまくいくかもしれない:

UPDATE financials.operator_summary_daily d 
SET osm_fos_id = m.fos_id 
FROM financials.operator_settlement_monthly m 
WHERE m.fos_opt_id = d.osm_opt_id 
AND date_trunc('month', d.osm_timestamp) = date_trunc('month', m.fos_timestamp) 
-- AND daily.osm_fos_id is null -- ?? Why is this here/commented out? 
+0

すばやくお返事ありがとうございました。編集した質問をご覧ください.JOINを使用して以来の条件は問題ではありません。そして、それを実装しようとする簡素化のおかげで! – itayw

+0

@ mr.kav:JOINはあなたが思うものではありません。 FROM句の2つのテーブルだけを結合します。多分あなたはMySQLのねじれたUPDATE構文に慣れているでしょうか?それでもWHERE句が必要です。私は声明を追加しました。あなたが実際に望むものかもしれないと推測します。もう一度簡略化されました。 –

+0

アーウィンありがとうございました、今はうまくいっていますが、正直言って私はまだこれがどうして起こったのか分かりません。私は別のクエリを追加しました。これは、id = idチェックをどこで実行するのかを使用しましたが、良い結果はありません。あなたの解決策は動作し、私は今からこのアプローチを使用しますが、どのデータベースがねじれているのかわかりません:) – itayw

0

あなたはあなたがする必要があるFROM

後の結果にクエリを更新するテーブルにリンクWHERE句を持っていません

update financials.operator_summary_daily set 
    osm_fos_id = fos_id 
from financials.operator_summary_daily daily 
join (
    select 
     osm_id, 
     fos_id 
    from financials.operator_summary_daily daily 
    join financials.operator_settlement_monthly on daily.osm_opt_id = fos_opt_id and date_trunc('month', daily.osm_timestamp)::timestamp = date_trunc('month', fos_timestamp)::timestamp --and daily.osm_fos_id is null 
) as result on result.osm_id = daily.osm_id 
WHERE daily.osm_id = financials.operator_summary_daily.osm_id -- condition to link 
+0

素早くお答えいただき、ありがとうございました。編集された質問をご覧ください.JOINを使用して以来の状況では問題ではありません。 – itayw

+1

問い合わせ* FROMの後の部分が* FROMの前の部分には何も関係していないので、問題が発生しています。更新する同じテーブルを参照しているということは、更新ステートメントに関連しているとは限りません。そうではない。 –

関連する問題