[英]SQL Joining two tables but overwriting the first if it exists in the second
我无法使此查询按我希望的方式工作。 我有两个具有几乎相同数据的表,但希望其中一个可以覆盖另一个(如果存在)。 一个例子比尝试解释要容易:
有未调整的余额表:
所需的输出将获得未调整的余额,并在其之上应用任何现有的调整(如果is_current = 1)...本质上将替换该行,但仍保留原始的未调整的current_balance。
所需的输出将是这样的:
这是我当前的查询无法正常工作...它正在翻转值并缺少current_balance。 我已经尝试了几个小时,却无法到达任何地方:
SELECT
*
FROM
(
SELECT
balance_adjustments.name,
balance_adjustments.user_id,
balance_adjustments.amount_owed,
balance_adjustments.when_to_pay,
balance_adjustments.current_balance
FROM
balance_adjustments
WHERE
balance_adjustments.when_to_pay = '2018-11-05'
AND balance_adjustments.is_current = true
UNION ALL
SELECT
unadjusted_balance.name,
unadjusted_balance.user_id,
unadjusted_balance.amount_owed,
unadjusted_balance.when_to_pay,
unadjusted_balance.current_balance
FROM
unadjusted_balance
LEFT OUTER JOIN balance_adjustments ON balance_adjustments.user_id = unadjusted_balance.user_id
AND balance_adjustments.name = unadjusted_balance.name
AND balance_adjustments.when_to_pay = unadjusted_balance.when_to_pay
AND balance_adjustments.is_current = true
WHERE
unadjusted_balance.when_to_pay = '2018-11-05'
AND balance_adjustments.name IS NULL
) AS table1
一些其他命令可帮助任何人设置此方案进行测试:
CREATE TABLE balance_adjustments
(
name varchar(30),
user_id varchar(30),
amount_owed float,
when_to_pay datetime,
current_balance float,
is_current boolean
);
CREATE TABLE unadjusted_balance
(
name varchar(30),
user_id varchar(30),
amount_owed float,
when_to_pay datetime,
current_balance float
);
insert into balance_adjustments values ('ricardo', '82340001', 100.00, '2018-11-05', null, 1)
insert into balance_adjustments values ('ricardo', '82340001', 33.00, '2018-11-05', null, 0)
insert into unadjusted_balance values ('joseph', '82340000', 2400.00, '2018-11-05', 4049.00)
insert into unadjusted_balance values ('ricardo', '82340001', 899.00, '2018-11-05', 500.00)
谢谢你的帮助
如果要使用余额调整覆盖未调整的余额,请执行以下操作:
如果不为空,则Coalesce将返回第一个值,否则返回下一个参数的值。 如果左联接未返回任何行,则总和的结果将为null。
询问
SELECT ub.name
, ub.user_id
, COALESCE(SUM(ba.amount_owed), ub.amount_owed) AS amount_owed
, ub.when_to_pay
, ub.current_balance
FROM @unadjusted_balance AS ub
LEFT JOIN @balance_adjustments AS ba ON ba.user_id = ub.user_id AND ba.is_current = 1
GROUP BY ub.name, ub.user_id, ub.amount_owed, ub.when_to_pay, ub.current_balance;
我不确定您是否可以在is_current
等于1的情况下进行多个调整,如果最多只能有一行,则忽略聚合和分组,只需将ba.amount_owed作为第一个参数传递即可合并。
如果您只想用balance_adjustments
表中is_current
为1的值替换amount_owed
(我假设这些值只有一个),那么简单的LEFT JOIN
和COALESCE
就足够了。 COALESCE
确保balance_adjustments
表中不匹配的行中的任何NULL
值都被unadjusted_balances
表中的原始值替换。 从您的问题尚不清楚,您是否也想替换when_to_pay
字段,我假设您在此查询中也有。 如果不这样做,只需更换COALESCE(ba.when_to_pay, ub.when_to_pay) AS when_to_pay
与ub.when_to_pay
。
SELECT ub.name, ub.user_id,
COALESCE(ba.amount_owed, ub.amount_owed) AS amount_owed,
COALESCE(ba.when_to_pay, ub.when_to_pay) AS when_to_pay,
ub.current_balance
FROM unadjusted_balance ub
LEFT JOIN balance_adjustments ba ON ba.user_id = ub.user_id AND ba.is_current
ORDER BY ub.name
输出:
name user_id amount_owed when_to_pay current_balance
joseph 82340000 2400 2018-11-05 00:00:00 4049
ricardo 82340001 100 2018-11-05 00:00:00 500
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.