[T-SQL] Как правильно JOIN'нить таблицу с самой собой?

agaaaa

Простой пример:
Есть таблица Table с полями ID, Order
Нужно по ID текущей записи получить ID следующей.
Следующая - такая, у которой Order минимально возможный из Order'ов, больших Order'а текущей.
Как с подзапросом сделать - понятно, но интересно, как без.

hprt

 
 
select top (1) with ties
a.id
, b.id
from
orders a
inner join orders b
on b.[order] > a.[order]
order by
row_number over (partition by a.id order by b.[order])

насчет правильности вопрос непонятный правда - скажем, этот кусок довольно нагляден, но работает точно медленнее, чем подзапрос с row_number и последующей фильтрацией по нему = 1 (row_number нельзя поместить в where). Ну и с подзапросом тоже может получиться быстрее

agaaaa

Как-то слишком длинно.
Что за with ties?
over, partition, имхо, ненужные сложности, можно и без этого
Вопрос в том - как?

hprt

Синтаксис можно посмотреть в БОЛ (у тебя ведь MSSQL, а не Sybase, да?)- в общем, вопросы "что есть" идут лесом, а так - скажи, что ты хочешь и что такое "over, partition, имхо, ненужные сложности, можно и без этого
Вопрос в том - как?" Давай скрипт для тестовых данных и говори, что не устраивает в нем. Если у тебя уже есть айдишник - подзапрос с очень большой вероятностью будет оптимальным вариантом.

korsika

Я может тебя не правильно понял, но посмотри тебе это надо?
create table #t(id int, sum1 decimal(10,2 tot_sum decimal(10,2

insert #t(id, sum1) values(1, 1.1)
insert #t(id, sum1) values(2, 1.2)
insert #t(id, sum1) values(3, 1.3)
insert #t(id, sum1) values(4, -0.5)

select * from #t

select t.id,min(t1.id) as id2
from #t t
join #t t1 on (t.sum1 < t1.sum1)
GROUP BY t.id
order by t.id

mbolik1

Внесу свои 5-ть копеек:
select t1_id, min(t2_id) from
(
select
t1.id t1_id, t2.id t2_id, rank over (partition by t1.id order by t2.order) rk
from
table t1
join table t2 on (t1.order < t2.order)
)
where rk = 1
group by t1_id

hprt

ave, Шурик - это как раз фильтрация по row_number, что я писал выше, группировка не нужна имхо. Но таки ждем, чего же хочет топикстартер

agaaaa

Забейте, всё оказалось проще - я название колонки order написал без скобочек.
SELECT TOP 1 SEL.ID FROM Table AS SEL 
JOIN Table AS C ON SEL.[Order] > C.[Order] WHERE C.ID = 'ID' ORDER BY SEL.[Order] ASC

mbolik1

 
SELECT TOP 1 SEL.ID FROM Table AS SEL 
JOIN Table AS C ON SEL.[Order] > C.[Order] WHERE C.ID = 'ID' ORDER BY SEL.[Order] ASC

Это был отличный пример как ненадо писать такие запросы.

agaaaa

Это был отличный пример как ненадо писать такие запросы.
Поясни

korsika

а можешь пояснить, почему вложенный запрос исключается из задания?
Вообщем интересна суть задачи :)

mbolik1

Зачем тебе вообще join если ты вытаскиваешь из первой таблицы ровно одну строку? Лишний раз проверить надёжность оптимизатора?

agaaaa

Зачем тебе вообще join если ты вытаскиваешь из первой таблицы ровно одну строку? Лишний раз проверить надёжность оптимизатора?
А где твой запрос без join?

agaaaa

а можешь пояснить, почему вложенный запрос исключается из задания?
Вообщем интересна суть задачи
Это вообще был квик вопрос.
Просто было интересно, как без них.

mbolik1

А где твой запрос без join?
select top 1 id from table where order > (select top 1 order from table where id = 'ID') order by order asc 

А в идеале нужно к моменту выполнения просто знать order, а не только id.
Оставить комментарий
Имя или ник:
Комментарий: