Вставка новой строки данных в таблицу на основе условия, которое сравнивается с другой таблицей

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть таблица отслеживания, которая отслеживает определенное число, связанное с нашими клиентами, под названием «Tracker». Таблица выглядит следующим образом:

 customer_id    value     date_of_value
11111            2          2020-12-14
23332            6          2021-01-15
 

Эта таблица берет эту информацию из другой таблицы под названием «Значения», которая является точно такой же таблицей, как указано выше, но без столбца date_of_value.
Эта таблица обновляется ежедневно, и значение, связанное с клиентом, перезаписывается новыми значениями.
Что я хотел бы иметь возможность сделать, так это создать небольшое задание, чтобы таблица «Отслеживание» просматривала таблицу «Значения», чтобы увидеть, было ли обновлено значение. Если это так, я хотел бы вставить новую строку в таблицу «Tracker» с идентификатором клиента, новым значением и датой изменения значения.
На мой взгляд, запрос будет выглядеть примерно так:

 CASE WHEN Tracker.value != Values.value
   THEN INSERT INTO Tracker (customer_id, value, date_of_value)
   VALUES (Values.id, values.value, GETDATE())
 

Я пытался использовать это вместе с инструкцией UPDATE, но ни один из них не работал.
В идеале таблица «Tracker» будет выглядеть следующим образом:

 customerr_id    value      date_of_value
11111             2           2020-12-14
2332              6           2021-01-15
11111             3           2021-01-22
2332              8           2021-01-24 
 

Как я могу настроить этот запрос таким образом, чтобы при создании задания вставлялась новая строка с обновленной информацией? Когда я попытался использовать метод ОБНОВЛЕНИЯ, он перезаписал информацию в таблице «Tracker».

Комментарии:

1. Вы можете преобразовать таблицу значений в временную таблицу с системной версией. Тогда все изменения ОБНОВЛЕНИЯ будут автоматически фиксироваться в одной транзакции

Ответ №1:

Хммм … Вам нужно самое последнее значение из tracker таблицы. Затем сравните это с существующими значениями и вставьте, где есть различия:

 INSERT INTO Tracker (customer_id, value, date_of_value)
    SELECT v.customer_id, v.value, GETDATE()
    FROM (SELECT v.*,
                 ROW_NUMBER() OVER (PARTITION BY v.customer_id ORDER BY v.value DESC) as seqnum
          FROM values v
         ) v LEFT JOIN
         Tracker t
         ON v.customer_id = t.customer_id AND
            v.value = t.value
    WHERE v.seqnum = 1 AND t.customer_id IS NULL;
 

Комментарии:

1. Я должен был упомянуть, что значения могут как уменьшаться, так и увеличиваться. Похоже, это выглядит как наивысшее значение.

Ответ №2:

Мы можем создать триггер в основной таблице для вставки новой строки в таблицу отслеживания:

 CREATE TRIGGER trg_Tracking
ON MainTable
AFTER INSERT, UPDATE AS

IF (NOT UPDATE(value) OR NOT EXISTS
    (SELECT customer_id, value FROM inserted
    EXCEPT
    SELECT customer_id, value FROM deleted))
    RETURN;        -- early bail-out if we can

INSERT Tracker (customerr_id, value, date_of_value)
SELECT customer_id, value, GETDATE()
FROM (
    SELECT customer_id, value FROM inserted
    EXCEPT     --make sure to compare inserted and deleted values (AFTER INSERT has empty deleted values)
    SELECT customer_id, value FROM deleted
) changed;

GO     -- No BEGIN and END as the whole batch is the trigger