#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
Комментариев нет:
Отправить комментарий