Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

Поиск последовательности в таблице

#sql_server


В БД есть таблица в два столбца с большим количеством записей. Первый столбец - id,
второй - числа с плавающей точкой.

Дана последовательность трёх чисел с плавающей точкой. Нужно узнать, встречается
ли такая последовательность в БД - допустим с 10 id по 12. Если есть - то нужен id
начального числа.

Как это лучше всего сделать с наименьшими энергозатратами? Выбрать в массив вхождения
по первому числу и в затем цикле проверить остальные 2? Но записей в ней очень много
- такая переборка займёт большое время.

Дополню, чтобы понятней задача была. Вот БД:


4.3422
5.3434
3.3243
4.2453
2.3445
и т.д.


Дана последовательность 3х чисел: 5.3434, 3.3243, 4.2453. Нужно найти эту последовательность
в базе данных - есть ли она вообще, а если есть, то вернуть что они находятся в том
же порядке со 2 id по 4. 
    


Ответы

Ответ 1



Стандартная задача на поиск подпоследовательности в последовательности. Далее два запроса, которые ищут все вхождения подпоследовательности в последовательность: 1) вариант для подпосл. из 3х элементов. работает только если в Id нет пропусков значений. 2) для любых подпоследовательностей. DECLARE @T1 TABLE(Id INT, Value MONEY) DECLARE @T2 TABLE(Id INT, Value MONEY) INSERT @T1 VALUES (1,1),(2,2),(3,3),(4,4),(5,3), (6,2),(7,3),(8,4),(9,3),(10,2) INSERT @T2 VALUES (1,2),(2,3),(3,4) --вариант для трёх, работает только если в Id нет пропусков значений. SELECT MIN(T1.Id) Id FROM @T1 T1 JOIN @T2 T2 ON T1.Value = T2.Value GROUP BY T1.Id - T2.Id HAVING COUNT(*) = 3 --более общий вариант, работает с любыми последовательностями SELECT MIN(T1.Id) Id FROM (SELECT ROW_NUMBER()OVER(ORDER BY Id)N,* FROM @T1)T1 JOIN (SELECT ROW_NUMBER()OVER(ORDER BY Id)N,COUNT(*)OVER()C,* FROM @T2)T2 ON T1.Value = T2.Value GROUP BY T1.N - T2.N HAVING COUNT(*)=MAX(C) UPD: если вы заранее знаете все три значения, то пожалуй лучше встроить конструктор таблицы прямо в запрос. Ещё 2 варианта: DECLARE @T1 TABLE(Id INT, Value MONEY) INSERT @T1 VALUES (1,1),(2,2),(3,3),(4,4),(5,3), (6,2),(7,3),(8,4),(9,3),(10,2) DECLARE @Param1 MONEY = 2, @Param2 MONEY = 3, @Param3 MONEY = 4 --В столбце Id таблички @T1 нет пропусков: SELECT MIN(T1.Id) Id FROM @T1 T1 JOIN (VALUES(1,@Param1),(2,@Param2),(3,@Param3))T2(Id, Value) ON T1.Value = T2.Value GROUP BY T1.Id - T2.Id HAVING COUNT(*)=3 --В столбце Id таблички @T1 есть пропуски: SELECT MIN(T1.Id) Id FROM (SELECT ROW_NUMBER()OVER(ORDER BY Id)N,* FROM @T1)T1 JOIN (VALUES(1,@Param1),(2,@Param2),(3,@Param3))T2(N, Value) ON T1.Value = T2.Value GROUP BY T1.N - T2.N HAVING COUNT(*)=3

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

Отправить комментарий