SQL объединяет две таблицы, но перезаписывает первую, если она существует во второй - PullRequest
0 голосов
/ 05 ноября 2018

Я не могу заставить этот запрос работать так, как я хочу. У меня есть две таблицы с почти идентичными данными, но я хочу, чтобы одна переопределила другую, если она существует Пример будет проще, чем пытаться объяснить:

Таблица несбалансированного баланса:

unadjusted_balance

и отдельная таблица корректировок для каждого баланса enter image description here

желаемый вывод берет нескорректированные сальдо и применяет любые существующие корректировки поверх него (если is_current = 1) ... по существу, заменяя строку, но сохраняя исходный нескорректированный current_balance.

желаемый результат будет примерно таким:

enter image description here

вот мой текущий запрос, который работает не так, как я хочу ... это переворачивание значений и отсутствие 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)

спасибо за любую помощь

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Если вы просто хотите заменить amount_owed значением из таблицы balance_adjustments, где is_current равно 1 (и я предполагаю, что есть только одно из этих значений), тогда простые LEFT JOIN и COALESCE будет достаточно. COALESCE гарантирует, что любые значения NULL из несопоставленных строк в таблице balance_adjustments будут заменены исходными значениями из таблицы 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

Демонстрация на dbfiddle

0 голосов
/ 06 ноября 2018

Если вы хотите переписать нескорректированный баланс с корректировками баланса, выполните следующие действия:

  • Выбрать все нескорректированные балансы.
  • Left Присоединяйтесь к корректировкам, чтобы вы могли получать любые корректировки, обязательно отфильтровывая тех, у кого is_current = 1.
  • Используйте сумму amount_owed в корректировках, чтобы получить сумму перезаписи.
  • Чтобы по умолчанию использовать оригинал, если нет корректировок, используйте объединение за пределами суммы и укажите исходную сумму в качестве второго параметра.

Coalesce вернет первое значение, если оно не равно нулю, или значение следующего параметра в противном случае. Результат агрегирования суммы будет нулевым, если из левого соединения не будет возвращено ни одной строки.

Запрос

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 в качестве первого параметра в объединении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...