2015-08-01 1 views
0

Проблема, которую я пытаюсь решить, - это перенаправление HTTP. Каждый раз, когда пользователь меняет заголовок статьи, создается новый URL-адрес, но старые URL-адреса должны указывать на последнюю статью.Как выбрать последнюю строку из ряда связанных строк

Можно изменить заголовок статьи несколько раз, чтобы таблица, в которой отслеживается изменение имени, имеет пару старых и новых URL-адресов.

Пример:

orange -> pear 
pear -> apple 
apple -> grape 

таблица выглядит следующим образом:

    Table "public.redirects" 
    Column |   Type   |  Modifiers 
----------+--------------------------+------------------------ 
from_url | character varying(200) | not null 
to_url | character varying(200) | not null 
code  | smallint     | not null default 301 
added | timestamp with time zone | not null default now() 
Indexes: 
    "redirects_pkey" PRIMARY KEY, btree (from) 

Я имею дело с бесконечными петлями во вставках, но проблема, что у меня есть, как выбрать последний URL, чтобы избежать выдача нескольких переадресаций.

Используя пример выше, если запрос для «оранжевого», я хочу отправить перенаправление прямо на «виноград». Можно ли достичь этого в одном запросе на выбор?

ответ

0

Вам нужен recursive query для этого:

with recursive all_redirects as 
(
    select from_url, 
      to_url, 
      1 as level 
    from redirects 
    where from_url = 'orange' 

    union all 

    select c.from_url, 
      c.to_url, 
      p.level + 1 
    from redirects c 
    join all_redirects p on p.to_url = c.from_url 
) 
select to_url 
from all_redirects 
order by level desc 
limit 1; 

SQLFiddle: http://sqlfiddle.com/#!15/358a7/1

Запрос будет извлечь выгоду из индекса на (from_url, to_url). При необходимости запрос может иметь дело с бесконечными циклами.

+0

Большое спасибо, это именно то, что я искал. После второй мысли в качестве меры предосторожности я решил заняться бесконечными циклами, мне это удалось, добавив 'where c.to_url! =" Orange "' ко второму выбору. –