#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