标签: hierarchy

查找分层字段的最高级别:有与没有 CTE

注意:此问题已更新以反映我们目前正在使用 MySQL,这样做后,我想看看如果我们切换到支持 CTE 的数据库会更容易。

我有一个带有主键id和外键的自引用表parent_id。

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment | 
| parent_id  | int(11)      | YES  |     | NULL    |                | 
| name       | varchar(255) | YES  |     | NULL    |                | 
| notes      | text         | YES  |     | NULL    |                | 
+------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

给定 a name,如何查询顶级父级?

给定 a name,如何查询id …

mysql hierarchy

65
推荐指数
3
解决办法
8万
查看次数

有人在生产中使用 HierarchyId 吗?它可靠吗?

是否有人在实际生产中使用 HierarchyId 使用合理大小的表,超过几千行?它可靠/性能好吗?到目前为止,我还没有发现任何与供应商无关的人推荐它,并且 Paul Nielsen在这里建议不要使用它。

您在实际生产系统中使用 HierarchyId 的经验是什么?

当您选择 HierarchyId 而不是其替代品时,您使用了哪些标准?

sql-server-2008 sql-server hierarchy

21
推荐指数
2
解决办法
8549
查看次数

父子树分层顺序

我必须跟踪 SQL Server 2008 R2 中的数据。SQLFiddle

架构:

创建表 [dbo].[ICFilters](
   [ICFilterID] [int] IDENTITY(1,1) 非空,
   [ParentID] [int] NOT NULL DEFAULT 0,
   [FilterDesc] [varchar](50) NOT NULL,
   [Active] [tinyint] NOT NULL DEFAULT 1,
 约束 [PK_ICFilters] 主键聚集 
 ( [ICFilterID] ASC ) 与 
    PAD_INDEX = 关闭,
    STATISTICS_NORECOMPUTE = 关闭,
    IGNORE_DUP_KEY = 关闭,
    ALLOW_ROW_LOCKS = 开,
    ALLOW_PAGE_LOCKS = 开
 ) 在 [主要]
) 在 [主要]

INSERT INTO [dbo].[ICFilters] (ParentID,FilterDesc,Active)
价值观 
(0,'产品类型',1),
(1,'ProdSubType_1',1),
(1,'ProdSubType_2',1),
(1,'ProdSubType_3',1),
(1,'ProdSubType_4',1),
(2,'PST_1.1',1),
(2,'PST_1.2',1),
(2,'PST_1.3',1),
(2,'PST_1.4',1),
(2,'PST_1.5',1),
(2,'PST_1.6',1),
(2,'PST_1.7',0),
(3,'PST_2.1',1),
(3,'PST_2.2',0),
(3,'PST_2.3',1),
(3,'PST_2.4',1), …

sql-server hierarchy order-by sql-server-2008-r2

21
推荐指数
1
解决办法
8万
查看次数

使用 SQL 遍历关系数据库中的树状数据

有没有办法在 SQL 中遍历树数据?我知道connect by在 Oracle 中,但是在其他 SQL 实现中还有另一种方法吗?我问是因为使用connect by比编写循环或递归函数来为每个结果运行查询更容易。

由于有些人似乎对短语“树数据”感到困惑,我将进一步解释:我的意思是关于具有parent_id或类似字段的表,该字段包含来自同一表中另一行的主键。

问题来自我在 Oracle 数据库中处理以这种方式存储的数据的经验,并且知道connect by其他 DBMS 中没有实现。如果要使用标准 SQL,则必须为每个想要向上的父表创建一个新表别名。这很容易失控。

tree hierarchy feature-comparison

16
推荐指数
3
解决办法
7764
查看次数

创建多个级别的层次结构,其中每个节点都有随机数量的子节点

我需要创建一些涉及层次结构的测试数据。我可以让它变得简单并做几个CROSS JOINs,但这会给我一个完全统一/没有任何变化的结构。这不仅看起来很乏味,而且测试数据缺乏变化有时会掩盖原本会发现的问题。所以,我想生成一个遵循以下规则的非统一层次结构:

  • 3 层深
    • 1 级随机 5 - 20 个节点
    • 级别 2 是 1 - 10 个节点,每个级别 1 的每个节点随机
    • 级别 3 是 1 - 5 个节点,每个级别 2 的每个节点随机
  • 所有分支都将有 3 层深。在这一点上,深度的均匀性是可以的。
  • 任何给定级别上的子节点的名称都可以重叠(即子节点的名称在同一级别的所有节点中不需要是唯一的)。
  • 术语“随机”在这里定义为伪随机,而不是唯一随机。这需要提及,因为术语“随机”通常用于表示“不产生重复的给定集合的随机排序”。我接受 random = random 并且如果级别 1 的每个节点的子节点数仅为 4、7 和 8,即使级别 1 上的 20 个节点每个节点的潜在分布为 1 - 10 个子节点,那很好,因为这就是随机。
  • 尽管使用嵌套WHILE循环可以很容易地做到这一点,但首选是找到一种基于集合的方法。一般而言,生成测试数据没有生产代码对效率的要求,但尝试基于集合的方法可能会更具教育意义,并有助于在未来找到基于集合的方法来解决问题。因此WHILE,不排除循环,但只有在不可能使用基于集合的方法时才能使用循环。
  • Set-based = 理想情况下是单个查询,无论 CTE、APPLY 等如何。因此使用现有或内联数字表很好。使用 WHILE / CURSOR / 程序方法是行不通的。我想将部分数据暂存到临时表或表变量中就可以了,只要操作都是基于集合的,没有循环。然而,话虽如此,单查询方法可能比多查询更受青睐,除非可以证明多查询方法实际上更好。另请记住,“更好”的构成通常是主观的;-)。还请记住,前一句中“典型地”的用法也是主观的。
  • 任何版本的 SQL Server(我想是 2005 和更新版本)都可以。
  • 只有纯 T-SQL:没有那些愚蠢的 SQLCLR 东西!!至少在生成数据方面。将使用 SQLCLR 创建目录和文件。但在这里,我只是专注于产生要创造的价值。 …

sql-server hierarchy random t-sql

16
推荐指数
2
解决办法
1万
查看次数

是否有一种基于集合的方法来加载/读取带有 HierarchyId 的树枝

我正在玩 HierarchyId,但我还没有想出一种基于集合的方法来执行以下操作:

  • 一次插入所有子树
  • 一次检索所有子树

这个问题与我之前的问题有关,我怀疑使用 HierarchyId 完成这两个任务的唯一方法是一次一个节点或一个级别。如果我使用的是物化路径,那么这两个操作都可以通过一个(且简单的)基于集合的命令轻松完成。

我错过了什么?

编辑:我也错过了移动子树的方法,但我是从 Mikael Eriksson 的评论中学到的

sql-server-2008 sql-server hierarchy sql-server-2008-r2

11
推荐指数
1
解决办法
777
查看次数

具有层次结构的表:创建约束以防止通过外键循环

假设我们有一个对自身有外键约束的表,如下所示:

CREATE TABLE Foo 
    (FooId BIGINT PRIMARY KEY,
     ParentFooId BIGINT,
     FOREIGN KEY([ParentFooId]) REFERENCES Foo ([FooId]) )

INSERT INTO Foo (FooId, ParentFooId) 
VALUES (1, NULL), (2, 1), (3, 2)

UPDATE Foo SET ParentFooId = 3 WHERE FooId = 1
Run Code Online (Sandbox Code Playgroud)

该表将有以下记录:

FooId  ParentFooId
-----  -----------
1      3
2      1
3      2
Run Code Online (Sandbox Code Playgroud)

在某些情况下,这种设计可能有意义(例如典型的“员工-老板-员工”关系),并且无论如何:我处于我的模式中有这种情况的情况。

不幸的是,这种设计允许数据记录中的循环,如上例所示。

那么我的问题是:

  1. 是否可以编写一个约束来检查这个?和
  2. 编写一个检查这个的约束是否可行?(如果只需要一定深度)

对于这个问题的第 (2) 部分,可能需要提及的是,我希望我的表中只有数百或在某些情况下可能有数千条记录,通常嵌套的深度不会超过大约 5 到 10 级。

附注。微软 SQL Server 2008


2012 年 3 月 14 日更新
有几个很好的答案。我现在已经接受了帮助我理解提到的可能性/可行性的那个。不过,还有其他几个很好的答案,其中一些还提供了实施建议,因此,如果您带着相同的问题来到这里,请查看所有答案;)

sql-server-2008 constraint hierarchy

10
推荐指数
3
解决办法
5228
查看次数

Oracle:如何查询分层表?

背景

这是为了构建我们将用于报告的一些视图。

我有一个位置表,关键字段是 "location" 和 "parent"。

这两个字段创建的结构在级别上是沿着公司名称 --> 校园名称 --> 建筑物名称 --> 楼层名称 --> 房间名称。在这种情况下,公司名称保持不变,校园名称保持不变。

位置的结构通常如下所示:

                                 +-----------+
                                 | Org. Name |
                                 +-----+-----+
                                       |
                                 +-----v-----+
           +--------------------+|Campus Name|+---+--+-------------+
           |                     +--+--------+    |                |
           |                        |             |                |
           |                        |             |                |
        +--+-----+           +------+-+        +--+----+       +---+---+
    +--+| BLDG-01|+--+       | BLDG-02|        |BLDG-03|       |Grounds|
    |   +--------+   |       +--------+        +-------+       +-------+
  +-+------+   +-----+--+
  |Floor-01|   |Basement+-------+
  +-+------+   +--------+       |
    |                           |
    |                           |
    | +----------+      +-------+--+
    +-+Room 1-001|      |Room B-002|
      +----------+      +----------+
Run Code Online (Sandbox Code Playgroud)

每个位置都链接回其父位置,最终是组织名称。目前,只有一个组织和一个校区。

目标

  • 我希望能够在“建筑物”级别查询任何给定位置下的所有位置。这样我就可以返回诸如在给定建筑物内的任何位置执行了多少工单之类的信息。 …

oracle query hierarchy view

10
推荐指数
2
解决办法
7335
查看次数

COUNT 行的父 id 等于我们在一个查询中父 id 为 0 的行

我想使用 MySQL 在一个查询中执行以下操作:

  • 抓取一个 parent_id 为 0 的行
  • 抓取我们抓取的具有 parent_id 为 0 的行的 parent_id 的所有行的计数

如何在一个查询中完成此操作?如果您需要更多信息,请告诉我,我很乐意为您提供帮助。我不是创建问题的专家,所以请告诉我您需要什么更多信息。

这是我现在正在做的一个例子:

select id from messages where parent_id=0
Run Code Online (Sandbox Code Playgroud)

进而

select count(id) from messages where parent_id={{previously_chosen_id}}
Run Code Online (Sandbox Code Playgroud)

如何获得一次性查询?就像是...

select id, count(records where parent_id=the id we just asked for)
Run Code Online (Sandbox Code Playgroud)

或者,有没有更好的方法来处理这个问题?你看,目前我必须运行大量查询才能找到计数,而我宁愿一次性完成。

mysql tree hierarchy

10
推荐指数
1
解决办法
3万
查看次数

hierarchyid CLR 是开源的吗?

内置的hierarchyid是一个CLR,它以高效的二进制形式存储路径,并提供其他有用的功能。

不幸的是,所表示的路径的深度是有限的,对于二叉树来说大约是 1427。对于必然会达到此限制的复杂现有应用程序,我想增加该限制。我不想改变类型的界面。我不相信我可以改变类型的接口而不将细微的错误引入所有必须更改的代码中。

我可以(理论上)创建一个“binhierarchyid”CLR UDT,它实现与hierarchyid 相同的接口,但只支持二叉树。这应该让我获得 ~7000 的深度,同时仍然保持在 900 字节的限制内。不知道这将是一项多大的事业。

这个hierarchyid CLR的来源是否在某处可用,以便我可以基于它创建自己的支持更深层次的结构?

sql-server hierarchy sql-clr

9
推荐指数
3
解决办法
361
查看次数