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
);

編集:
迅速な回答をありがとうございますが、whereは必要ありません。結合条件は左ではなく、包括的であり、更新のために一致した行のみをレンダリングする必要があります。したがって、37K(参加基準を満たすもの)のうち1963レコードのみを更新する必要があります。私が間違っている?

答え:正しいスクリプト:

    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;
  • 複雑な結合は、内部クエリが「デバッグ」の目的でテーブル全体のサブセットのみを返すようにしようとした結果です。

再度、感謝します!

4

2 に答える 2

1

WHEREUPDATEに条件はありません。

このステートメントは行を更新し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?
于 2012-04-11T15:23:31.570 に答える
0

WHEREクエリの後に結果に更新されるテーブルにリンクする句がありませんFROM

次のようなことをする必要があります

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
于 2012-04-11T15:24:34.267 に答える