簡體   English   中英

SQL連接兩個表,但是如果第二個表中存在第一個表,則覆蓋第一個表

[英]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)

謝謝你的幫助

如果要使用余額調整覆蓋未調整的余額,請執行以下操作:

  • 選擇所有未調整的余額。
  • 左加入調整項,以便獲得任何調整項,確保濾除is_current = 1的那些項。
  • 使用調整中的amount_owed的總和來獲取覆蓋量。
  • 為了在沒有調整的情況下默認為原始值,請在總和之外使用合並,並將原始量用作第二個參數。

如果不為空,則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 JOINCOALESCE就足夠了。 COALESCE確保balance_adjustments表中不匹配的行中的任何NULL值都被unadjusted_balances表中的原始值替換。 從您的問題尚不清楚,您是否也想替換when_to_pay字段,我假設您在此查詢中也有。 如果不這樣做,只需更換COALESCE(ba.when_to_pay, ub.when_to_pay) AS when_to_payub.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

dbfiddle上的演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM