2012-04-27 2 views
3

У меня есть таблица, которая имеет следующие столбцысоздания псевдо связанный список в SQL

table: route 
columns: id, location, order_id 

и имеет такие значения, как

id, location, order_id 
1, London, 12 
2, Amsterdam, 102 
3, Berlin, 90 
5, Paris, 19 

Можно ли сделать SQL SELECT заявление в Postgres который вернет каждую строку вместе с id со следующим самым высоким order_id? Так что я хочу что-то вроде ...

id, location, order_id, next_id 
1, London, 12, 5 
2, Amsterdam, 102, NULL 
3, Berlin, 90, 2 
5, Paris, 19, 3 

Благодаря

ответ

6
select 
    id, 
    location, 
    order_id, 
    lag(id) over (order by order_id desc) as next_id 
from your_table 
+0

Вау, это круто, я никогда не слышал о функции задержки. Как преформатант является функцией? Делает ли это lag() один раз для всей таблицы? Или это будет порядок для каждой строки? – dan

+0

Это ** аналитическая функция **. В этом случае двигатель упорядочивает строки, а затем для каждой строки получает значение из строки прецедента. Итак, у вас есть полное сканирование таблицы и сортировка. –

+0

, и если вы хотите запаздывать более одного столбца, то есть добавить отставание (местоположение) поверх (order by order_id desc) как next_location. Будет ли это второй сорт? И если мне также нужен предыдущий идентификатор и местоположение, это будет третий и четвертый сорт? – dan

1

Создание первого тестового стенда:

CREATE TABLE route (id int4, location varchar(20), order_id int4); 
INSERT INTO route VALUES 
    (1,'London',12),(2,'Amsterdam',102), 
    (3,'Berlin',90),(5,'Paris',19); 

Запрос:

WITH ranked AS (
    SELECT id,location,order_id,rank() OVER (ORDER BY order_id) 
     FROM route) 
SELECT b.id, b.location, b.order_id, n.id 
    FROM ranked b 
    LEFT JOIN ranked n ON b.rank+1=n.rank 
    ORDER BY b.id; 

Вы можете прочитать на функции окна в documentation ,

0

да:

select * , 
(select top 1 id from routes_table where order_id > main.order_id order by 1 desc) 
from routes_table main 
+0

Да, я придумал нечто похожее к этому, но я думал, что производительность будет ужасной, что с необходимостью делать подзапрос для каждой строки – dan

+0

Это не допустимая конструкция PostgreSQL. – vyegorov

+0

Это мой запрос, который действителен PostgreSQL: select * from mytable l left join mytable r на r.order_id = (выберите min (s.order_id) из mytable s, где s.order_id> l.order_id) – dan

Смежные вопросы