Отображение периодического значения в новом столбце на основе значения другого столбца
Мне бы хотелось, чтобы запрос, основанный на поле "Периодичность", повторял бы каждые N строк значение True, сгруппированное по полю "Тип". Я думаю, что могу объяснить лучше на примере:
Имея следующую таблицу...
id type periodicity
1 1 3
2 1 3
3 1 3
4 1 3
5 1 3
6 1 3
7 1 3
8 1 3
9 1 3
10 2 2
11 2 2
12 2 2
13 2 2
14 2 2
15 2 2
16 2 2
... Я хотел бы иметь запрос, который будет возвращать что-то вроде этого...
id type periodicity execute_operation
1 1 3 TRUE
2 1 3 FALSE
3 1 3 FALSE
4 1 3 TRUE
5 1 3 FALSE
6 1 3 FALSE
7 1 3 TRUE
8 1 3 FALSE
9 1 3 FALSE
10 2 2 TRUE
11 2 2 FALSE
12 2 2 TRUE
13 2 2 FALSE
14 2 2 TRUE
15 2 2 FALSE
16 2 2 TRUE
Для строк, где поле "тип" равно 1, поле "execute_operation" будет помечено как True каждые 3 строки (значение, определенное в поле "периодичность").
Для строк, имеющих "тип" равен 2, поле "execute_operation" будет помечено как True каждые 2 строки.
Как мне этого добиться?
3 ответа
Вы можете объединить оконную функцию ROW_NUMBER с оператором по модулю.
Порядковый номер последовательности каждой группы (1, 2, 3, ...). По модулю возвращается позиция в последовательности путем вычисления остатка. Пример:
1 Мод 3 = 1.
2 Mod 3 = 2.
3 Мод 3 = 0.
Если мод числа строк по периодичности равен 1, то возвращается значение true.
WITH [Sample] AS
(
-- CTE provides sample data.
SELECT
*
FROM
(
VALUES
(1, 1, 3),
(2, 1, 3),
(3, 1, 3),
(4, 1, 3),
(5, 1, 3),
(6, 1, 3),
(7, 1, 3),
(8, 1, 3),
(9, 1, 3),
(10, 2, 2),
(11, 2, 2),
(12, 2, 2),
(13, 2, 2),
(14, 2, 2),
(15, 2, 2),
(16, 2, 2)
) AS x(id, [type], periodicity)
)
SELECT
s.id,
s.[type],
s.periodicity,
CASE ROW_NUMBER() OVER (PARTITION BY s.[type] ORDER BY s.id) % periodicity
WHEN 1 THEN 1
ELSE 0
END AS execute_operation
FROM
[Sample] AS s
ORDER BY
s.id
;
Я сделал, как показано ниже, для достижения требуемого результата. Вместо '%' (мод) вы можете сохранить периодичность. И я предположил, что ваш столбец идентификатора будет иметь последовательные номера, поэтому я использовал его из-за устранения row_number
SELECT ID,
TYPE,
CASE
WHEN RNO = 1
AND TYPE = 1 THEN 'TRUE'
WHEN RNO = 2
AND TYPE = 2 THEN 'TRUE'
ELSE 'FALSE'
END STATUS
FROM (SELECT ID,
TYPE,
CASE
WHEN TYPE = 1 THEN Replace(ID%3, 0, 3)
ELSE Replace(ID%2, 0, 2)
END RNO
FROM #TABLE1)A
Вы можете попробовать что-то вроде ниже, пожалуйста, замените на соответствующие имена столбцов,
update tbl_Sample set Operation = 0 --default to false
;WITH CTE
AS
(
select *
,ROW_NUMBER() over(Partition by Periodicity order by ID) 'R'
from tbl_Sample
)
UPDATE CTE
SET Operation = 1
WHERE R%Periodicity = 1