Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 SQL запрос, выборка по маске среди пар значений  [new]
Kaj09
Member

Откуда:
Сообщений: 50
Здравствуйте!

Есть N непересекающихся подмножеств следующего типа:

14090-15200
15201-15290
15291-15890
15891-15999
16000-16010

Для простоты я взял 5 пар. Все данные хранятся в таблице из трёх столбцев: "from-to","from","to" (каждое значение обязательно 5 символов).
Задача: при вводе с клавиатуры посимвольно очередной цифры выводить в таблицу соответствующих пар, например:
- Сперва ввожу "1". Логика должна быть такой, что рассматриваются все варианты 1хххх: от 10000 до 19999. Соответственно вывод должен содержать все пары, так как они все удовлетворяют данному условию.
- затем, например, ввожу "5", получаю "15". Вывод должен быть таким:
14090-15200
15201-15290
15291-15890
15891-15999
- затем вводим "8", итого "158". На выходе:
15291-15890
15891-15999
- затем "9", итого "1589". На выходе тоже самое:
15291-15890
15891-15999
- и наконец "7", итого "15897". На выходе:
15891-15999.

Помогите подготовить универсальный SQL запрос, который бы решал данную задачу. Спасибо
29 апр 13, 22:50    [14246771]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
так как-то
Guest
select * from T
where left(@param+'0000', 5) between [from] and [to]
29 апр 13, 23:04    [14246819]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
так,
Guest
если тип [from] and [to] - числовой
select * from T
where cast(left(cast(@param as varchar)+'0000', 5) as int) between [from] and [to]
29 апр 13, 23:08    [14246828]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Kaj09
Member

Откуда:
Сообщений: 50
Как Вы, гость, написали - не подходит. Потому что, например на втором шаге, при таком вызове:

select * from T where left('15'+'000', 5) between [from] and [to]


вывод будет содержать только пару 14090-15200.
А по условию задачи выводу будут соответствовать все пары кроме последней:

14090-15200 //поскольку 15ххх, например 15109 принадлежит данному подмножеству
15201-15290 //аналогично
15291-15890 //аналогично
15891-15999 //аналогично
29 апр 13, 23:21    [14246869]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
так,
Guest
Kaj09
Как Вы, гость, написали - не подходит.

да, согласен - не то...
так, а какой тип, всё-таки у "from","to" ?

если int, то так будет правильно
declare @param int, @param1 int
set @param = 15897
set @param1 = cast(left(cast(@param as varchar)+'0000', 5) as int) / @param

select [from], [to]
from @t
where @param between [from]/@param1 and [to]/@param1 

если текст, так
select [from], [to]
from @t
where @param between left([from], len(@param)) and left([to], len(@param))  

не думаю, что это оптимально ...
но на "лучше" у меня идей нет :(
29 апр 13, 23:56    [14246955]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
FantomGood
Member

Откуда: Херсон
Сообщений: 335
Kaj09
Как Вы, гость, написали - не подходит. Потому что, например на втором шаге, при таком вызове:

select * from T where left('15'+'000', 5) between [from] and [to]


вывод будет содержать только пару 14090-15200.
А по условию задачи выводу будут соответствовать все пары кроме последней:

14090-15200 //поскольку 15ххх, например 15109 принадлежит данному подмножеству
15201-15290 //аналогично
15291-15890 //аналогично
15891-15999 //аналогично


15ххх -Ваша маска задает диапазон 15000-15999, поэтому нужно искать пересечение диапазонов
select * from T where [from] between  left('15'+'000', 5)  and left('15'+'999', 5) or [to] between  left('15'+'000', 5)  and left('15'+'999', 5) 
30 апр 13, 10:17    [14247815]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
invm
Member

Откуда: Москва
Сообщений: 9401
declare @t table (f varchar(5), t varchar(5));

insert into @t
values
 ('14090', '15200'),
 ('15201', '15290'),
 ('15291', '15890'),
 ('15891', '15999'),
 ('16000', '16010');

declare @v varchar(10) = '15';

select
 *
from
 @t
where
 f <= left(@v + '99999', 5) and
 t >= left(@v + '00000', 5) and
 f >= left(@v + '00000', 5);
Адаптировать для чисел труда не составит.
30 апр 13, 11:35    [14248357]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
SELECT  * FROM [Table] T WHERE
EXISTS(SELECT * FROM Patterns P WHERE T.Field LIKE '['+P.[from-to]+']');
Так что ли?
Или шаблоны не в своей таблице шаблонов, а прямо в рабочей таблице?
SELECT * FROM [Table] WHERE Field LIKE '['+[from-to]+']';
30 апр 13, 11:43    [14248445]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
declare @t table (f varchar(5), t varchar(5));

insert into @t
values
 ('14090', '15200'),
 ('15201', '15290'),
 ('15291', '15890'),
 ('15891', '15999'),
 ('16000', '16010');

declare @v varchar(10) = '152';


select * from @t where f like @v+'%'  OR t like @v+'%' 
30 апр 13, 12:20    [14248695]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
iap
SELECT  * FROM [Table] T WHERE
EXISTS(SELECT * FROM Patterns P WHERE T.Field LIKE '['+P.[from-to]+']');

Так что ли?
Или шаблоны не в своей таблице шаблонов, а прямо в рабочей таблице?
SELECT * FROM [Table] WHERE Field LIKE '['+[from-to]+']';
Ой, какую фигню написал! Не смотрите! :))
30 апр 13, 12:36    [14248803]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Мистер Хенки
declare @t table (f varchar(5), t varchar(5));

insert into @t
values
 ('14090', '15200'),
 ('15201', '15290'),
 ('15291', '15890'),
 ('15891', '15999'),
 ('16000', '16010');

declare @v varchar(10) = '152';


select * from @t where f like @v+'%'  OR t like @v+'%' 

Не пойдёт:
declare @t table (f varchar(5), t varchar(5));

insert into @t
values
 ('14090', '15200'),
 ('15201', '15290'),
 ('15291', '15890'),
 ('15891', '15999'),
 ('16000', '16010');

declare @v varchar(10) = '1524';


select * from @t where f like @v+'%'  OR t like @v+'%' -- (0 row(s) affected)
30 апр 13, 12:53    [14248917]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Гость333
Member

Откуда:
Сообщений: 3683
invm
declare @t table (f varchar(5), t varchar(5));

insert into @t
values
 ('14090', '15200'),
 ('15201', '15290'),
 ('15291', '15890'),
 ('15891', '15999'),
 ('16000', '16010');

declare @v varchar(10) = '15';

select
 *
from
 @t
where
 f <= left(@v + '99999', 5) and
 t >= left(@v + '00000', 5) and
 f >= left(@v + '00000', 5);
Адаптировать для чисел труда не составит.

Условие " f >= left(@v + '00000', 5)" лишнее, т.к. отсекает диапазон 14090-15200.
30 апр 13, 12:54    [14248927]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
select * from @t where (cast(f as int) <= cast(left(@v +'0000',5) as int) and cast(t as int) >= cast(left(@v+'9999',5) as int) )
or (cast(f as int) >= cast(left(@v +'0000',5) as int)  and cast(f as int) <= cast(left(@v+'9999',5) as int))
or (cast(t as int) >= cast(left(@v +'0000',5) as int) and cast(t as int) <= cast(left(@v+'9999',5) as int) )
30 апр 13, 13:17    [14249041]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Гость333
invm
declare @t table (f varchar(5), t varchar(5));

insert into @t
values
 ('14090', '15200'),
 ('15201', '15290'),
 ('15291', '15890'),
 ('15891', '15999'),
 ('16000', '16010');

declare @v varchar(10) = '15';

select
 *
from
 @t
where
 f <= left(@v + '99999', 5) and
 t >= left(@v + '00000', 5) and
 f >= left(@v + '00000', 5);
Адаптировать для чисел труда не составит.

Условие " f >= left(@v + '00000', 5)" лишнее, т.к. отсекает диапазон 14090-15200.


declare @v varchar(10) = '154';
))))
30 апр 13, 13:19    [14249055]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Мистер Хенки
Гость333
пропущено...

Условие " f >= left(@v + '00000', 5)" лишнее, т.к. отсекает диапазон 14090-15200.


declare @v varchar(10) = '154';
))))

Не совсем уловил мысль, если убираем указанное условие, то для 154 выведется результат 15291-15890, вроде это правильно?
30 апр 13, 13:27    [14249101]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
invm
Member

Откуда: Москва
Сообщений: 9401
Гость333
Условие " f >= left(@v + '00000', 5)" лишнее, т.к. отсекает диапазон 14090-15200.
Ага. Специально добавил, чтобы отсечь, а оказалось не нужно :)
30 апр 13, 13:35    [14249150]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Гость333
Мистер Хенки
пропущено...


declare @v varchar(10) = '154';
))))

Не совсем уловил мысль, если убираем указанное условие, то для 154 выведется результат 15291-15890, вроде это правильно?

а да, если убрать условие f >= left(@v + '00000', 5), то правильно будет работать, а я чего то намудрил. Простая задача ведь на пересечение интервалов.
30 апр 13, 13:41    [14249187]     Ответить | Цитировать Сообщить модератору
 Re: SQL запрос, выборка по маске среди пар значений  [new]
Kaj09
Member

Откуда:
Сообщений: 50
Спасибо огромное всем! Особенно invm за правильный предложенный вариант ответа и за поправку Гостя333 в этом ответе
30 апр 13, 17:59    [14250776]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить