UPDATE2這裏是一個函數,它peforms好,因爲搜索那張只能在路徑,從父母開始:
create or replace function get_item(path text[])
returns items
as
$$
with recursive cte as (
select i.id, i.name, i.parent_id, 1 as level
from items as i
where i.parent_id is null and i.name = $1[1]
union all
select i.id, i.name, i.parent_id, c.level + 1
from items as i
inner join cte as c on c.id = i.parent_id
where i.name = $1[level + 1]
)
select c.id, c.parent_id, c.name
from cte as c
where c.level = array_length($1, 1)
$$
language sql;
sql fiddle demo
更新我認爲你可以做遞歸遍歷。我寫的這個版本的SQL,所以這是一個有點亂,因爲熱膨脹係數,但它是可以寫一個函數:
with recursive cte_path as (
select array['holiday', 'spain', '2013'] as arr
), cte as (
select i.id, i.name, i.parent_id, 1 as level
from items as i
cross join cte_path as p
where i.parent_id is null and name = p.arr[1]
union all
select i.id, i.name, i.parent_id, c.level + 1
from items as i
inner join cte as c on c.id = i.parent_id
cross join cte_path as p
where i.name = p.arr[level + 1]
)
select c.*
from cte as c
cross join cte_path as p
where level = array_length(p.arr, 1)
sql fiddle demo
,或者你可以爲所有使用遞歸的元素的構建路徑CTE爲和accumuate您的路徑到數組或字符串:
with recursive cte as (
select i.id, i.name, i.parent_id, i.name::text as path
from items as i
where i.parent_id is null
union all
select i.id, i.name, i.parent_id, c.path || '->' || i.name::text as path
from items as i
inner join cte as c on c.id = i.parent_id
)
select *
from cte
where path = 'holiday->spain->2013';
或
with recursive cte as (
select i.id, i.name, i.parent_id, array[i.name::text] as path
from items as i
where i.parent_id is null
union all
select i.id, i.name, i.parent_id, c.path || array[i.name::text] as path
from items as i
inner join cte as c on c.id = i.parent_id
)
select *
from cte
where path = array['holiday', 'spain', '2013']
sql fiddle demo
的問題還不是很清楚。什麼是「最後節點」?如果您已經擁有「完整路徑」,您需要搜索什麼?你的表格定義也不是很有用。也許添加一些示例數據的問題? – wildplasser
額外的問題:1)i1上面是否有其他_unmatched_節點?在i1和i2之間,在i2和i3之間?低於i3?如果是這樣:你是否也想要檢索這些文件? 2)是重要的路徑中的{節假日,圖像,西班牙}的_order_,或者可能以任何順序出現?順便說一句:'parent_id'上的唯一索引是不可能的(並且是錯誤的) – wildplasser
我剛剛添加了一個sqlfiddle。最後一個節點是路徑的最後一項(a,b,c,d - > d)。我只有名字,而不是任何ID。節點的名稱不是全球唯一的,這就是爲什麼我必須檢查所有父母。我現在正在使用連接來完成此操作,但連接的數量等於路徑元素的數量。哪個不好。 – gucki