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

Откуда: Москва
Сообщений: 375
Всем добрый вечер.

Недавно отвечал на тесты, для соискателей.
Был там вот такой вопрос:

Есть таблица T, с произвольным набором значений в поле id, как одним select получить крайние значения от заданного значения id на входе.
Пример:
T.id =
12
34
76
89
1234
1254
6789
3456

На вход для select подаем id=1254, на выходе должны быть два значения 1234 и 6789

Я предоставил следующий ответ

Select MIN(id) f0 from T Where id>1254
UNION ALL
Select MAX(id) f0 from Where id<1254

Судя по отзыву ответ посчитали неправильным.

Вопрос из любопытства: как можно ответить на данный вопрос?

Заранее спасибо
19 окт 15, 22:16    [18299825]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Алексей,

Может они хотели. Предыдущий - следующий в 12том что ли появились
19 окт 15, 22:25    [18299852]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
такто два селекта в ответе
Guest
Алексей,

это называется "угадай, что я загадал".

результат-то правильный (разве что селектов формально два).
вопрос скорее был про десяток вариантов, как это можно сделать, а не про какой-то один конкретный.
19 окт 15, 22:29    [18299867]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
TukTuk
Guest
SELECT Prev,Post FROM
(
SELECT id,
LAG(id) OVER(ORDER BY Z) Prev,
LEAD(id) OVER(ORDER BY Z) Post
FROM T
) TT
WHERE id = 1254

Z --мутная сортировка в зависимости от входа

+ может в id есть повторы
19 окт 15, 22:36    [18299900]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
TukTuk
Guest
Результат не правильный, т.к. если вход будет такой:
1250
12
34
76
89
1234
1254
6789
3456
6999
То резульат будет не верный.
19 окт 15, 22:42    [18299915]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Алексей
Member

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

Я процитировал вопрос как мне его прислали.
19 окт 15, 22:49    [18299925]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
invm
Member

Откуда: Москва
Сообщений: 9844
Алексей
Вопрос из любопытства: как можно ответить на данный вопрос?
В данной постановке задачи, правильный ответ - никак.
Потому что не определен критерий "крайнее значение от заданного". Можно только догадываться, что авторы задачи имели в виду.

Ну и вы не один такой соискатель у них - https://www.sql.ru/forum/1176488-1/kak-v-tablice-kuche-poluchit-poryadok-strok
19 окт 15, 22:50    [18299927]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Алексей
Member

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

Спасибо, не знал.....
19 окт 15, 22:54    [18299934]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
o-o
Guest
а вот и иллюстрация к соседней теме "идиотски сформулированный запрос"
+


Как в таблице куче получить порядок строк
19 окт 15, 22:56    [18299939]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Алексей
Member

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

Спасибо.
Интересно было разобраться лыжи не едут или ......
19 окт 15, 22:58    [18299946]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
TukTuk
Guest
SELECT Prev,Post FROM
(
SELECT id,
LAG(id) OVER(ORDER BY %%physloc%% ) Prev,
LEAD(id) OVER(ORDER BY %%physloc%% ) Post
FROM T
) TT
WHERE id = 1254

Вот ответ
19 окт 15, 23:05    [18299958]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Алексей
Member

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

Благодарю.
19 окт 15, 23:09    [18299962]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
invm
Member

Откуда: Москва
Сообщений: 9844
TukTuk
Вот ответ
Во-первых, select'ов два :)
Во-вторых, читайте приведенную ссылку - там объясняется почему ваш ответ неверен.
19 окт 15, 23:21    [18299979]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
TukTuk
Guest
DECLARE @val INT = 1254
SELECT TOP 1 WITH TIES 
 IIF(id=@val,@val,NULL),
 IIF(id=@val,LAG(id) OVER(ORDER BY %%physloc%%),NULL) Prev,
 IIF(id=@val,LEAD(id) OVER(ORDER BY %%physloc%%),NULL) Post
FROM T
ORDER BY 1 DESC


=))

CREATE TABLE T (id INT)

INSERT INTO T 
VALUES(1250),
(12),
(34),
(76),
(89),
(1234),
(1254),
(6789),
(3456),
(1254),
(6999)


Работает вроде
19 окт 15, 23:33    [18299996]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
o-o
Guest
да там не только ответ неверен,
еще можно в другое вляпаться...

итак, конструирую пример под это дело,
имитируя многопользовательскую среду.
типа, пока я набиваю мои значения,
в сеседней сессии дропают табличку,
да так удачно, что как раз то опрашиваемое далее значение
помещается на страницу, идущую раньше всех других в файле.
ну и чтобы проще было показать, беру значения типа char(8000),
чтобы 1 значение на страницу было.
угадайте, во что вылился запрос
create table dbo.filler(id int identity primary key clustered, c char(8000));
go

insert into dbo.filler default values;
go 200

create table dbo.t (id char(8000));
go
insert into dbo.t(id) values (cast (12 as char));
insert into dbo.t(id) values (cast (34 as char));
insert into dbo.t(id) values (cast (76 as char));
insert into dbo.t(id) values (cast (89 as char));
insert into dbo.t(id) values (cast (1234 as char));

drop table dbo.filler;
go

insert into dbo.t(id) values (cast (1254 as char));
insert into dbo.t(id) values (cast (6789 as char));
insert into dbo.t(id) values (cast (3456 as char));
go

SELECT Prev,Post FROM
(
SELECT id,
LAG(id) OVER(ORDER BY %%physloc%% ) Prev,
LEAD(id) OVER(ORDER BY %%physloc%% ) Post
FROM T
) TT
WHERE id = 1254

Msg 1701, Level 16, State 1, Line 1
Creating or altering table 'WorkTable' failed because the minimum row size would be 16032, including 7 bytes of internal overhead. This exceeds the maximum allowable table row size of 8094 bytes.

вот такое вот последствие совместного использования lead, lag.
а считать предыдущее/следующее совместно старыми способами с нумерацией и самосоединением -- сколько угодно
19 окт 15, 23:48    [18300015]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
o-o
Guest
TukTuk
...
Работает вроде

по ссылке разъясняется,
что вы на сервере не один,
пока вы вставляете, как думаете, "последовательно",
ситуация может 100 раз измениться,
заполнив страницу, вы переходите к следующей, к-ая может оказаться _ранее_идущей_ в файле данных.
на начало вставки она была занята, теперь свободна, данные легли туда.
и как он(server) там распределил страницы, вы не знаете.
и сортитуя согласно физическому расположению, вы вообще без понятия, какой ответ получите
19 окт 15, 23:54    [18300032]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
TukTuk
Guest
Никто о последовательности и не говорил, поэтому все нормально. Я не вижу проблем даже если страница будет не на том месте и начальный порядок изменится.
20 окт 15, 00:15    [18300062]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
o-o
Guest
TukTuk
Никто о последовательности и не говорил, поэтому все нормально. Я не вижу проблем даже если страница будет не на том месте и начальный порядок изменится.

т.е. что не сойдется с ответом из задания, это ничего?
например, не окажется никакого следующего у 1254, хотя заносили все числа и в том порядке, как написано?
что же тогда за условие в задаче?
"получите мне хоть что-нибудь"?
там желают получить "крайние", что же тогда является критерием "крайности",
если "ни о какой последовательности речи не идет"?
20 окт 15, 01:00    [18300116]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
o-o
Guest
TukTuk
даже если страница будет не на том месте

вот как раз страница всегда будет на своем месте, нумерация у ней есть,
в отличие от чисел из дебильного задания.
20 окт 15, 01:03    [18300126]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Алексей

Вопрос из любопытства: как можно ответить на данный вопрос?



Select MIN(id), MAX(id) from T Where id in (12,34,76,89,1234,1254,6789,3456)
20 окт 15, 10:38    [18300913]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8834
Шайтан-майтан:

declare @T table (id INT)

INSERT @T 
VALUES(1250),(12),(34),(76),(89),(1234),(1254),(6789),(3456),(1254),(6999)

select case when max(id) < 1254 then MAX(id) else MIN(id) end f0
from @T
where id <> 1254
group by case when id < 1254 then 0 else 1 end
20 окт 15, 11:54    [18301607]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
MasterZiv
Алексей
Вопрос из любопытства: как можно ответить на данный вопрос?



Select MIN(id), MAX(id) from T Where id in (12,34,76,89,1234,1254,6789,3456)


"крайние значения от заданного значения id на входе." ?
20 окт 15, 11:56    [18301629]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8834
Winnipuh,

а что, понято буквально, не написано же в задании "соседние значения".
20 окт 15, 12:01    [18301661]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Владислав Колосов
Winnipuh,

а что, понято буквально, не написано же в задании "соседние значения".


да, но надо было как-то привязать заданный ид к запросу, типа

Select MIN(id), MAX(id) from T Where id in (12,34,76,89,1234,1254,6789,3456) and id <> @id


20 окт 15, 12:03    [18301686]     Ответить | Цитировать Сообщить модератору
 Re: Академ вопрос  [new]
o-o
Guest
Winnipuh
MasterZiv
Select MIN(id), MAX(id) from T Where id in (12,34,76,89,1234,1254,6789,3456)

"крайние значения от заданного значения id на входе." ?

да все ок,
ведь крайний -- это или находящийся с краю, или экстремальный.
именно по этой причине у любого списка значений "краев" всегда 2 (могут и совпадать).
но т.к. нам тут втирают, что упорядоченность отсутствует, о краях говорить не приходится.
остаются экстремумы -- min и max.
---
супер-составители вопросов сперва должы с русским разобраться, если хотят, чтоб их понимали.
еще раз: то, что они хотят -- это "соседние" значения.
и для определения соседства необходимо определение порядка.
нет порядка -- нет соседства. все!
20 окт 15, 12:14    [18301796]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить