我想我失去了它,任何人都可以解释为什么我会遇到以下情况: 这是我的疑问:
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的整个表上执行,并更新所有39条记录。
我在这里缺少什么?
表:
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
);
编辑:
感谢您的快速解答,但是不应该需要一个地方,连接条件不是LEFT,它是包含的,并且应该只渲染匹配的更新行。因此,应更新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;
再次感谢!
答案 0 :(得分: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?
答案 1 :(得分: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