#sql-server
#sql-сервер
Вопрос:
У меня есть History
таблица, как показано ниже:
ID | GroupCode | Category | TimeStamp
--- ----------- ---------- -----------
1 | x | shoes | 2016-09-01
2 | y | blach | 2016-09-01
History
таблица обновляется каждый месяц, и в таблицу вставляется одна запись для каждой GroupCode
.
У меня также есть Current
таблица, которая содержит последнюю позицию.
До или после обновления History
таблицы с текущей позицией я хотел бы узнать Category
, изменилось ли значение с прошлого месяца на этот месяц.
Мне нужно сравнить последнее Category
с текущим Category
и, если оно изменилось, отметить CategoryChanged
его в Current
таблице.
Current
таблица:
ID | GroupCode | Category | CategoryChanged
--- ----------- ---------- ----------------
1 | x | shoes | True
2 | y | blah | False
Я пытался добиться этого с INNER JOIN
помощью, но у меня возникли трудности INNER JOIN
с последними записями месяца и года в History
таблице, но безуспешно.
Комментарии:
1. можете ли вы опубликовать запрос, который вы пробовали?
Ответ №1:
--get highest group code based on timestamp
;with History
as
(select top 1 with ties groupcode,category
from
history
order by
row_number() over (partition by group code order by timestamp desc) as rownum
)
--now do a left join with current table
select
ct.ID,
ct.GroupCode,
ct.Category,
case when ct.category=ht.category or ht.category is null then 'False'
else 'true'
end as 'changed'
from
currenttable ct
left join
history ht
on ht.groupcode=ct.groupcode
используйте ниже для обновления, после проверки правильности выбранных значений..
update ct
set ct.category=
case when ct.category=ht.category or ht.category is null then 'False'
else 'true'
end
from
currenttable ct
left join
history ht
on ht.groupcode=ct.groupcode
Комментарии:
1. Как мне обновить столбец CategoryChanged с помощью этого?
2. Я не думаю, что этот код будет работать для вас, CTE в первом запросе выбирает только одну запись, она выбирает самую новую запись для одной конкретной группы случайным образом — поэтому, если у вас есть несколько групп для проверки, это не сработает. Второй запрос на обновление пытается изменить категорию на ‘true’ или ‘false’
3. @AndrewDeighton: Cte предоставляет мне последнюю категорию для всех кодов групп на основе метки времени, а не случайным образом
4. запрос имеет проблемы с синтаксисом. не могли бы вы обновить запрос?
5. вы должны использовать вышеуказанное обновление вместо выбора после cte
Ответ №2:
если вы создаете CTE, в котором записи истории имеют rown_numbwer для каждого группового кода, упорядоченного по убыванию даты, то вас интересуют строки 1 И 2, ПОЭТОМУ ВЫ МОЖЕТЕ присоединиться к своему CTE в GroupCode и выбрать записи 1 и 2, вы можете увидеть, изменилась ли категория между строками 1 и 2
;WITH CTE AS (SELECT *, row_number() OVER (PARTITION BY GroupCode ORDER BY TimeStamp Desc) RN FROM History)
SELECT
C1.ID,
C1.GroupCode,
C1.Category,
CASE WHEN C1.Category = C2.Category THEN
'false'
else
'true'
end AS CategoryChanged
FROM CTE C1
JOIN
CTE C2
ON C1.GroupCode = C2.GroupCode
AND C1.Rn=1 AND C2.RN = 2;
если у вас есть нулевые категории, вы можете избежать с помощью — КСТАТИ, вам нужно будет научиться обрабатывать нули так, как вы хотите их обрабатывать — вы не можете ожидать, что люди будут публиковать здесь, думая о NULLS, которые вы никогда не упоминали навсегда! И происходит, чтобы понять, что вы хотите с ними делать, если на то пошло
;WITH CTE AS (SELECT *, row_number() OVER (PARTITION BY GroupCode ORDER BY TimeStamp Desc) RN FROM History)
SELECT
C1.ID,
C1.GroupCode,
C1.Category,
CASE WHEN C1.Category = C2.Category OR C1.Category IS NULL AND C2.Category IS NULL THEN
'false'
else
'true'
end AS CategoryChanged
FROM CTE C1
JOIN
CTE C2
ON C1.GroupCode = C2.GroupCode
AND C1.Rn=1 AND C2.RN = 2;
Комментарии:
1. Если категория равна нулю в обоих, это возвращает true?
2. вы здесь слишком требовательны, вы знаете, вы действительно не дали понять, что бы вы хотели сделать, если бы оба имени были «НУЛЕВЫМИ» (или даже если это могло произойти). Также вы лишь смутно упомянули, что ожидали, что произойдет какое-то обновление — детали этого пока никак не ясны.
3. Я приношу извинения. Да, вы правы. Я поспешил задать вопрос вместо того, чтобы тратить время на четкое описание того, чего я хотел бы достичь. Я постараюсь обновить свой вопрос позже.
4. @akd — все в порядке, извинения приняты, был раздражительным — я вижу, вы и здесь оказали помощь — я должен был это проверить!