Using Recursive Common table expressions to represent Tree structures
http://www.postgresonline.com/journal/archives/131-Using-Recursive-Common-table-expressions-to-represent-Tree-structures.html
Tree Problem and was based on PostgreSQL 7.4 technology.
We'll repeat the text here for completeness and demonstrate the PostgreSQL 8.4 that solves this and more efficiently.
Suppose you are tracking supplies and have a field called si_item and
another called si_parentid.
The parent keeps track of what subclass a supply item belongs to. E.g.
you have paper parent that has subclasses such as recycled,
non-recycled. When someone takes supplies, you want to return the fully
qualified name e.g. Paper->Recycled->20 Lb
Below is what the structure of your table looks like.
si_id int, si_parentid int, si_item. In your table are the following entries
si_id | si_parentid | si_item |
---|---|---|
1 | Paper | |
2 | 1 | Recycled |
3 | 2 | 20 lb |
4 | 2 | 40 lb |
5 | 1 | Non-Recycled |
6 | 5 | 20 lb |
7 | 5 | 40 lb |
8 | 5 | Scraps |
Solution
CREATE TABLE supplyitem(si_id integer PRIMARY KEY, si_parentid integer, si_item varchar(100));
--load up the table (multirow constructor introduced in 8.2)
INSERT INTO supplyitem(si_id,si_parentid, si_item)
VALUES (1, NULL, 'Paper'),
(2,1, 'Recycled'),
(3,2, '20 lb'),
(4,2, '40 lb'),
(5,1, 'Non-Recycled'),
(6,5, '20 lb'),
(7,5, '40 lb'),
(8,5, 'Scraps');
--Recursive query (introduced in 8.4 returns fully qualified name)
WITH RECURSIVE supplytree AS
(SELECT si_id, si_item, si_parentid, CAST(si_item As varchar(1000)) As si_item_fullname
FROM supplyitem
WHERE si_parentid IS NULL
UNION ALL
SELECT si.si_id,si.si_item,
si.si_parentid,
CAST(sp.si_item_fullname || '->' || si.si_item As varchar(1000)) As si_item_fullname
FROM supplyitem As si
INNER JOIN supplytree AS sp
ON (si.si_parentid = sp.si_id)
)
SELECT si_id, si_item_fullname
FROM supplytree
ORDER BY si_item_fullname;
Result looks like
si_id | si_item_fullname
------+-----------------------------
1 | Paper
5 | Paper->Non-Recycled
6 | Paper->Non-Recycled->20 lb
7 | Paper->Non-Recycled->40 lb
8 | Paper->Non-Recycled->Scraps
2 | Paper->Recycled
3 | Paper->Recycled->20 lb
4 | Paper->Recycled->40 lb
- Using HStore for Archiving
- Using wget directly from PostgreSQL using COPY FROM PROGRAM
- Saying Happy Valentine in PostGIS
- Foreign Data Wrap (FDW) Text Array, hstore, and Jagged Arrays
- Finding contiguous primary keys
- String Aggregation in PostgreSQL, SQL Server, and MySQL
- Using LTree to Represent and Query Hierarchy and Tree Structures
- Allocating People into Groups with SQL the Sequel
- PostgresQL 8.4: Common Table Expressions (CTE), performance improvement, precalculated functions revisited
This post was mentioned on Twitter by roblb: Using Recursive
Common table expressions to represent Tree structures: A very long time
ago, we wrote .. http://bit.ly/Flne3 #postgres
Tracked: Jan 04, 21:19
Tracked: Aug 20, 00:58
(Linear | Threaded)
A couple of observations:
* Unless the length 1000 has some significance, use TEXT instead of
VARCHAR(1000).
* It might well be both faster and more correct to push items into an array
and use array_to_string() in the outer SELECT, and it won't be subject to
sorting anomalies.
WITH RECURSIVE supplytree AS
(
SELECT
si_id,
si_item,
si_parentid,
ARRAY[si_item] AS si_item_array
FROM supplyitem
WHERE si_parentid IS NULL
UNION ALL
SELECT
si.si_id,si.si_item,
si.si_parentid,
sp.si_item_array || si.si_item As si_item_array
FROM
supplyitem As si
JOIN
supplytree AS sp
ON (si.si_parentid = sp.si_id)
)
SELECT
si_id,
array_to_string(si_item_array, '->') AS si_item_fullname
FROM supplytree
ORDER BY si_item_array;
http://www.postgresql.org/docs/current/static/ltree.html
I'am not saying than WITH RECURSIVE is bad .. just that, there are simpler solution sometimes ;-)
will have to give it a test drive sometime. I think the only thing
against it is that its a PostgreSQL specific feature where as the CTE is
more ANSI portable (except for possiblyt the word RECURSIVE)
Couple of ways -- you could write a function as we demonstrated in
linked article, but that is not as suitable for multiple sets since it
would probably do a subquery for each record.
You coulde also take our example and limit with a WHERE clause but that is much slower than it could be.
The other way would be to recurse backward from the child to the parent.
So instead of starting at parent nodes -- you start at the child node
and keep on unioning until you hit a parent with no parent. Will have
to write that up sometime.
--Recursive query (introduced in 8.4 returns fully qualified name)
WITH RECURSIVE supplytree AS
(SELECT si_id, si_item, si_parentid, CAST(si_item As varchar(1000)) As si_item_fullname
FROM supplyitem
WHERE si_item in( '40 lb')
UNION ALL
SELECT si.si_id,si.si_item,
si.si_parentid,
CAST(si.si_item || '->' || sp.si_item_fullname As varchar(1000)) As si_item_fullname
FROM supplyitem As si
INNER JOIN supplytree AS sp
ON (si.si_id = sp.si_parentid)
)
SELECT si_id, si_item_fullname
FROM supplytree where si_parentid is null
ORDER BY si_item_fullname;
table tema
-field tema_id (is the identificator)
-field nombre (is the name)
-field padre_id (is the parent id)
WITH RECURSIVE tema_tree AS (
SELECT tema_id, nombre, padre_id, nombre||'' full_name
FROM tema
WHERE padre_id IS NULL
UNION ALL
SELECT t.tema_id, t.nombre, t.padre_id, tt.full_name||' -> '||t.nombre full_name
FROM tema t
JOIN tema_tree tt ON t.padre_id = tt.tema_id
)
SELECT tema_id, full_name
FROM tema_tree
ORDER BY 2
Using Recursive Common table expressions to represent Tree structures的更多相关文章
- PostgreSQL: WITH Queries (Common Table Expressions)
WITH 允许在 SELECT 语句中定义"表"的表达式,这个"表"的表达式称之为"公共表表达式(Common Table Expression)&q ...
- The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.
https://stackoverflow.com/questions/30045871/sorting-the-view-based-on-frequency-in-sql-server Just ...
- Common Table Expressions (CTE)
子查询有时使用起来很麻烦,因为所有的过滤和匹配逻辑都必须集成到子查询表达式中.如果只需要执行一个任务,且只需要使用一次杳询表达式,子查询是很好的选择.但子查询不能被重用,也不能很好地支持多个需求.这个 ...
- leetcode 235. Lowest Common Ancestor of a Binary Search Tree 236. Lowest Common Ancestor of a Binary Tree
https://www.cnblogs.com/grandyang/p/4641968.html http://www.cnblogs.com/grandyang/p/4640572.html 利用二 ...
- 【LeetCode】236. Lowest Common Ancestor of a Binary Tree
Lowest Common Ancestor of a Binary Tree Given a binary tree, find the lowest common ancestor (LCA) o ...
- CTE(Common Table Expression) 公用表表达式
在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以 使用公用表表达式的方法.公用表表达式(Common Tabl ...
- Leetcode之236. Lowest Common Ancestor of a Binary Tree Medium
236. Lowest Common Ancestor of a Binary Tree Medium https://leetcode.com/problems/lowest-common-ance ...
- 88 Lowest Common Ancestor of a Binary Tree
原题网址:https://www.lintcode.com/problem/lowest-common-ancestor-of-a-binary-tree/description 描述 给定一棵二叉树 ...
- 【刷题-LeetCode】236. Lowest Common Ancestor of a Binary Tree
Lowest Common Ancestor of a Binary Tree Given a binary tree, find the lowest common ancestor (LCA) o ...
随机推荐
- vb6里面dim和set的区别
dim是作用于变量 声明变量并分配存储空间 set作用于对象 将对象引用赋给变量或属性 例子: dim A as collection set A=new collection 等效于 di ...
- mysql修改密码
mysql修改password >mysqladmin -u root -p password newpassword 就这么简单
- Java基础,输入输出
package hanqi.test; import java.io.File; import java.io.IOException; public class Test02 { public st ...
- struts1的一些基本用法和操作
入职两周了,项目是用struts1+ibatis框架搭建的,数据库是oracle,其他还行,关键是struts1之前没用用过,所以只好在网上狂查文档,最后大致整理了一些struts1的基本使用方法. ...
- 关于移动开发的一些想法和认识--Android和iOS
微信公众账号很久没更新了,发一点自己最近的想法和内容. 之前和朋友做了一个项目,现在在跟一些风投,大公司里面的几家在谈合作和投资的事宜,从这个过程中也了解到了一些信息. 关于移动平台的应用开发与游戏开 ...
- JS的IE和Firefox兼容性
以下以 IE 代替 Internet Explorer,以 MF 代替 Mozzila Firefox 0.px的问题 obj.style.left = ”100px”; obj.style.top ...
- PHP面试出场率较高的题目<转载>
--------------------PHP部分--------------------- PHP中几个输出函数echo,print(),print_r(),sprintf(),var_dump() ...
- Linux - 日志文件
Linux日志文件绝大多数存放在/var/log目录,其中一些日志文件由应用程序创建,其他的则通过syslog来创建. Linux系统日志文件通过syslog守护程序在syslog套接字/dev/lo ...
- sql初始化XML操作
/// <summary> /// 添加记录 /// </summary> /// <param name="sender"></para ...
- java中map插入相同的key
测试用例: package test; import org.junit.Test; import po.Person; import java.util.HashMap; import java.u ...