简体   繁体   English

SQL查询组织结构图?

[英]SQL Query for an Organization Chart?

I feel that this is likely a common problem, but from my google searching I can't find a solution quite as specific to my problem. 我觉得这可能是一个常见的问题,但是从我的Google搜索中,我找不到针对我的问题的解决方案。

I have a list of Organizations (table) in my database and I need to be able to run queries based on their hierarchy. 我的数据库中有一个组织列表(表),我需要能够根据其层次结构运行查询。 For example, if you query the highest Organization, I would want to return the Id's of all the Organizations listed under that Organization. 例如,如果您查询最高的组织,我想返回该组织下列出的所有组织的ID。 Further, if I query an organization sort of mid-range, I want only the Organization Id's listed under that Organization. 此外,如果我查询的是中等范围的组织,则只希望在该组织下列出组织ID。

What is the best way to a) set up the database schema and b) query? a)设置数据库架构和b)查询的最佳方法是什么? I want to only have to send the topmost Organization Id and then get the Id's under that Organization. 我只需要发送最高的组织ID,然后获取该组织下的ID。

I think that makes sense, but I can clarify if necessary. 我认为这是有道理的,但如有必要,我可以澄清。

As promised in my comment, I dug up an article on how to store hierarchies in a database that allows constant-time retrieval of arbitrary subtrees. 正如我的评论中所承诺的那样,我挖掘了一篇有关如何在数据库中存储层次结构的文章 ,该数据库允许恒定时间检索任意子树。 I think it will suit your needs much better than the answer currently marked as accepted, both in ease of use and speed of access. 我认为,无论是在易用性还是访问速度上,它都比当前标记为接受的答案更好地满足您的需求。 I could swear I saw this same concept on wikipedia originally, but I can't find it now. 我可以发誓最初在Wikipedia上看到过相同的概念,但是现在找不到了。 It's apparently called a "modified preorder tree traversal". 显然,它被称为“修改后的预定树遍历”。 The gist of it is you number each node in the tree twice, while doing a depth-first traversal, once on the way down, and once on the way back up (ie when you're unrolling the stack, in a recursive implementation). 要点是您对树中的每个节点编号两次,同时进行深度优先遍历,一次在向下,一次在向上(例如,在递归实现中展开堆栈时) 。 This means that the children of a given node have all their numbers in between the two numbers of that node. 这意味着给定节点的子代的所有数字都在该节点的两个数字之间。 Throw an index on those columns and you've got really fast lookups. 在这些列上添加索引,您将获得非常快速的查找。 I'm sure that's a terrible explanation, so read the article, which goes into more depth and includes pictures. 我敢肯定这是一个糟糕的解释,因此请阅读这篇文章,它会更深入地介绍图片。

One simple way is to store the organization's parentage in a text field, like: 一种简单的方法是将组织的父母身份存储在文本字段中,例如:

SALES-EUROPE-NORTH SALES-EUROPE-NORTH

To search for every sales organization, you can query on SALES-%. 要搜索每个销售组织,您可以查询SALES-%。 For each European sales org, query on SALES-EUROPE-%. 对于每个欧洲销售组织,查询SALES-EUROPE-%。

If you rename an organization, take care to update its child organizations as well. 如果重命名组织,请注意也要更新其子组织。

This keeps it simple, without recursion, at the cost of some flexibility. 这使它变得简单(无需递归),但付出了一定的灵活性。

The easy way is to have a ParentID column, which is a foreign key to the ID column in the same table, NULL for root nodes. 简单的方法是拥有一个ParentID列,这是同一表中ID列的外键,对于根节点则为NULL。 But this method has some drawbacks. 但是这种方法有一些缺点。

Nested sets are an efficient way to store trees in an relational database. 嵌套集是在关系数据库中存储树的有效方法。

You could have an Organization have an id PK and a parent FK reference to the id. 您可以让一个组织具有一个ID PK和对该ID的父FK引用。 Then for the query, use (if your database backend supports them) recursive queries, aka Common Table Expressions. 然后对于查询,使用(如果数据库后端支持)递归查询,也就是通用表表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM