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

Откуда: Екатеринбург
Сообщений: 138
Добрый день!

Подскажите как написать следующий запрос, допустим есть последовательность значений 12, 34, 25, 56, 48, надо найти соседние элементы допустим числа 25, т.е. слева будет 12, а справа 34.
Как написать такой запрос?
31 июл 12, 09:58    [12938546]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Centraloff,
эта последовательность в виде строки задана? и если соседние для 25, почему не - слева 34, справа 56?
31 июл 12, 10:04    [12938573]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Centraloff
Member

Откуда: Екатеринбург
Сообщений: 138
SomewhereSomehow,

Нет, не в виде строки, это поле одной из таблиц, тип поля int
31 июл 12, 10:06    [12938586]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Centraloff
Member

Откуда: Екатеринбург
Сообщений: 138
SomewhereSomehow,

Надо найти ближайшее меньшее число и ближайшее большее
31 июл 12, 10:07    [12938590]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Владимир СА
Member

Откуда:
Сообщений: 7863
DECLARE @t table (mint int);
insert into @t (mint) values 
(12),(34),(25),(56),(48),(10);

/* Пусть относительно числа 25 */
DECLARE @t_int int = 25;

select top 1 *
FROM @t
WHERE mint < @t_int
UNION ALL
SELECT @t_int
UNION ALL
select top 1 *
FROM @t
WHERE mint > @t_int;
31 июл 12, 10:20    [12938657]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Centraloff,

сервер-то SQL2012?
31 июл 12, 10:23    [12938670]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Centraloff
Member

Откуда: Екатеринбург
Сообщений: 138
Владимир СА,

Спасибо, но это работает конкретно для числа 25, для 48 и 34 например уже не работает

P.S. сервер sql2005
31 июл 12, 10:30    [12938732]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Centraloff,

в лоб вот так вот можно
declare @t table(a int)
insert @t values (12), (34), (25), (56), (48);
declare @v int = 25;

with 
n as (select *, rn = row_number() over(order by a) from @t),
p as (select pos = rn from n where a = @v)
select
	*
from
	n
	cross join p
where
	n.rn = p.pos-1 or
	n.rn = p.pos+1
;
31 июл 12, 10:30    [12938733]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Centraloff
Member

Откуда: Екатеринбург
Сообщений: 138
SomewhereSomehow,

Я так понимаю это для 2008 или 2012?
На 2005 выдает ошибку

Msg 319, Level 15, State 1, Line 24
Неправильный синтаксис около ключевого слова "with". Если данная инструкция является обобщенным табличным выражением или предложением xmlnamespaces, предыдущую инструкцию необходимо завершать точкой с запятой.
Msg 102, Level 15, State 1, Line 25
Неправильный синтаксис около конструкции ",".
31 июл 12, 10:37    [12938784]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Centraloff,

Да не, под 2005 тож должно работать. Перед with точку с запятой ставьте. Ну и инициализацию поменяйте типа такого.
+
declare @t table(a int)
insert @t values (12); 
insert @t values (34); 
insert @t values (25);
insert @t values (56);
insert @t values (48);
declare @v int;
set @v = 25;

with
n as (select *, rn = row_number() over(order by a) from @t),
p as (select top(1) pos = rn from n where a = @v)
select
	*
from
	n
	cross join p
where
	n.rn = p.pos-1 or	
	n.rn = p.pos+1
;
31 июл 12, 10:41    [12938809]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Centraloff
SomewhereSomehow,

Я так понимаю это для 2008 или 2012?
На 2005 выдает ошибку

Msg 319, Level 15, State 1, Line 24
Неправильный синтаксис около ключевого слова "with". Если данная инструкция является обобщенным табличным выражением или предложением xmlnamespaces, предыдущую инструкцию необходимо завершать точкой с запятой.
Msg 102, Level 15, State 1, Line 25
Неправильный синтаксис около конструкции ",".
Вместо values()()... -> select union all select union all select ...
Вместо declare @v int = 25; -> declare @v int; set @v = 25;
31 июл 12, 10:41    [12938812]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Владимир СА
Member

Откуда:
Сообщений: 7863
DECLARE @t table (mint int);
insert into @t (mint) values 
(12),(34),(25),(56),(48),(10);

DECLARE @t_int int = 48;

select top 1 mint, ROW_NUMBER() OVER(ORDER BY mint DESC) FROM @t WHERE mint < @t_int
UNION ALL
SELECT @t_int, 2
UNION ALL
select top 1 mint, 3 FROM @t WHERE mint > @t_int;
31 июл 12, 10:44    [12938829]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Centraloff
Member

Откуда: Екатеринбург
Сообщений: 138
SomewhereSomehow,


Огромное спасибо, действительно работает, точку с запятой только не дописал перед with.
31 июл 12, 10:47    [12938857]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Владимир СА
Member

Откуда:
Сообщений: 7863
Владимир СА
DECLARE @t_int int = 48;

select top 1 mint, ROW_NUMBER() OVER(ORDER BY mint DESC) FROM @t WHERE mint < @t_int
UNION ALL
SELECT @t_int, 2
UNION ALL
select top 1 mint, 3 FROM @t WHERE mint > @t_int;
Не так
select top 1 mint, ROW_NUMBER() OVER(ORDER BY mint DESC) FROM @t WHERE mint < @t_int
UNION ALL
SELECT @t_int, null
UNION ALL
select top 1 mint, ROW_NUMBER() OVER(ORDER BY mint ASC) FROM @t WHERE mint > @t_int
31 июл 12, 10:52    [12938901]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
Centraloff
Member

Откуда: Екатеринбург
Сообщений: 138
Владимир СА,

Спасибо большое.
31 июл 12, 10:58    [12938948]     Ответить | Цитировать Сообщить модератору
 Re: Найти соседние элементы  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Centraloff,

Ещё один способ:
declare @t table(a int)
insert @t values (12), (34), (25), (56), (48);

;with N as (
    SELECT *
     ,row_number() over(order by a)   AS M1
     ,row_number() over(order by a) +1 AS M2
     ,row_number() over(order by a) -1 AS M3
    FROM @t
)
SELECT 
     P1.a 
    ,P2.a V1
    ,P3.a V2
FROM N P1
    LEFT JOIN N P2 ON P1.M1 =P2.M2
    LEFT JOIN N P3 ON P1.M1 =P3.M3
31 июл 12, 11:41    [12939310]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить