我觉得我失去了它,任何人都可以解释为什么我会遇到以下: 这里是我的查询:更新(加入)
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
);
编辑:
谢谢你的快速解答,但不应该有需要的地方,连接条件不剩,这是包容性的,只有应该呈现匹配行进行更新。因此,应该更新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子句作为其他意见建议。我仍然不明白pgsql在更新记录时如何处理JOIN。
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;
- 这个复杂的连接是我的努力确保内部查询只返回整个表的子集“调试”宗旨的结果。
再次感谢!
感谢您的快速回答,请参阅编辑的问题,应该不是因为使用JOIN条件的问题。并感谢您的简化,实施它! – itayw 2012-04-11 15:28:46
@ mr.kav:JOIN不符合您的想法。它只加入FROM子句中的两个表。也许你习惯于MySQL的扭曲UPDATE语法?你仍然需要一个WHERE子句。我添加了一个声明 - 猜测这可能是你真正想要的。再简化一次。 – 2012-04-11 15:32:12
谢谢Erwin,现在就开始工作了,但说实话,我仍然不知道为什么会发生这种情况。我添加了另一个我尝试使用的查询,它强制执行id = id检查哪里,没有好的结果。你的解决方案的工作原理,我将从现在开始使用这种方法,但我不确定哪个是扭曲的db :) – itayw 2012-04-11 15:46:55