我的日期以树形结构组织。
以下内容适用(Oracle SQL语法):
CREATE TABLE TREE
(
NAME VARCHAR2(20),
ID NUMBER(10, 0),
PARENT NUMBER(10, 0)
)
;
INSERT INTO "TREE" (NAME, ID) VALUES ('a', '1');
INSERT INTO "TREE" (NAME, ID, PARENT) VALUES ('a.1', '2', '1');
INSERT INTO "TREE" (NAME, ID, PARENT) VALUES ('a.2', '3', '1');
INSERT INTO "TREE" (NAME, ID, PARENT) VALUES ('a.2.1', '4', '3');
INSERT INTO "TREE" (NAME, ID, PARENT) VALUES ('a.2.2', '5', '3');
INSERT INTO "TREE" (NAME, ID) VALUES ('b', '6');
我想通过id返回完整的树,所以对于查询:
select name, id <<<TODO LOGIC>> where id = 1
我会得到
| name | id |
| a | 1 |
| a.1 | 2 |
| a.2 | 3 |
| a.2.1 | 4 |
| a.2.2 | 5 |
我会得到一个子树:
select name, id <<<TODO LOGIC>> where id = 3
我会得到
| name | id |
| a.2 | 3 |
| a.2.1 | 4 |
| a.2.2 | 5 |
对于平面入口b,它将得到
select name, id <<<TODO LOGIC>> where id = 6
我会得到
| name | id |
| b | 6 |
似乎简单的遗漏联接查询无法实现此目的,或者我错过了什么?
以下查询确实返回完整结构,但在开始使用 where 语句进行过滤时,它会失败。
select t1.id t1Id, t2.id t2Id, t1.name t1Name, t2.name t2Name from tree t1 left outer join tree t2 on t1.id = t2.parent
答案 0 :(得分:3)
如果您有树结构,则可能需要分层查询。这是:
select t.*
from tree t
connect by prior t.id = t.parent
start with t.id = :id
order siblings by t.id
有关详细信息,请参阅Hierarchical Queries。
答案 1 :(得分:2)
您可以在Oracle上使用start with - connect by语法。如果我没弄错的话,就像这样
select * from Tree t
start with t.ID = 1 connect by prior t.ID = t.Parent
但是我没有Oracle立即检查它。也许是prior t.Parent = t.ID
。请注意,有时可能会很慢,请谨慎使用。
替代方法是创建表来存储节点之间的所有间接关系(不仅仅是a-a.1,还有a-a.2.1等)。您可以使用PL / SQL递归存储过程填充它。两种方式:
简单的方法是制作一个完成间接表填充的程序。您可以在运行报告之前调用它。
如果您需要即时效果,则应编写重新填充程序,以便仅为树中的一条记录更新间接关系。然后禁止直接插入和更新Tree并强制它们通过存储的PL / SQL过程(如InsertTree / UpdateTree)进行,这些过程将调用过程以间接关系更新表。
答案 2 :(得分:0)
您可以使用union
,并且您需要限制树的深度,以便可以在一个查询中选择它。
SELECT id, name
FROM TREE as node
WHERE
node.id = :id
UNION
SELECT child1.id, child1.name
FROM TREE as node
inner join TREE as child1 on node.id = child1.parent
WHERE
node.id = :id
UNION
SELECT child2.id, child2.name
FROM TREE as node
inner join TREE as child1 on node.id = child1.parent
inner join TREE as child2 on child1.id = child2.parent
WHERE
node.id = :id
这里的问题是,SQL在递归方面非常糟糕(虽然关系结构实际上非常好)。
要使其完全动态化,请对树中的每个级别使用查询,或者如果有任何可用的话,请使用特定于数据库引擎的SQL扩展。