标签: recursive

如何在无向循环图中对所有链接对象进行分组

我有一张桌子,上面有客户及其联合客户。例如,客户 1 有一个联合客户 2。客户 1 也是客户 3 的联合客户。

我正在尝试将所有链接的客户分组并为他们分配相同的 GroupCustNo。下表1-2相连,3-1相连。所以2-3也有联系。因此,下表中从 1 到 8 的所有客户都相互关联,并且将具有相同的 GroupCustNo。

 tbl_GroupCustomers:

CustNo   JtCustNo  GroupCustNo    
---      -------     ------   
1           2          null
2           null       null
3           1          null
4           1          null
4           5          null
5           6          null
5           7          null
6           null       null
7           null       null
8           5          null
Run Code Online (Sandbox Code Playgroud)

我写的递归存储过程如下。我在每个 CustNo 的 while 循环中调用它:

exec usp_UpdateGroupCustomerNo 1, 1 存储过程对大多数客户成功运行但吐了

某些客户的递归限制达到 32 错误。这些客户拥有许多联合客户,同时也是其他客户的联合客户。

似乎递归在这里不起作用,我对如何进行感到茫然。请让我知道是否有任何替代方法可以解决此问题。

CREATE PROCEDURE [dbo].[usp_UpdateGroupCustomerNo]
     @MainCustNo int, @GrpNo int
AS 
    declare @JtCustNo int; declare @MainCustNo2 int; …
Run Code Online (Sandbox Code Playgroud)

sql-server cte recursive

5
推荐指数
1
解决办法
187
查看次数

为什么这个 CTE 会立即返回大部分结果,但需要几分钟才能完成?

我有一个大致像这样的架构(这是我实际架构的简化):

CREATE TABLE foo (
    key1 NUMERIC(6) NOT NULL,
    key2 VARCHAR(32) NOT NULL,
    val VARCHAR(255) NULL,
    CONSTRAINT foo_pk PRIMARY KEY (key1, key2) --PK on key1, key2
    )
GO
CREATE TABLE bar (
    key1 NUMERIC(6) NOT NULL,
    key2 VARCHAR(32) NOT NULL,
    val VARCHAR(255) NULL,
    CONSTRAINT bar_pk PRIMARY KEY (key1, key2) --PK on key1, key2
    )
GO
CREATE TABLE aliases (
    id VARCHAR(32) NOT NULL PRIMARY KEY,
    text VARCHAR(255) NOT NULL,
    CONSTRAINT aliases_uk UNIQUE (text) --PK on id, unique constraint on text …
Run Code Online (Sandbox Code Playgroud)

performance sql-server-2008 sql-server recursive query-performance

5
推荐指数
1
解决办法
231
查看次数

PostgreSQL - 检索树中给定子节点的所有 ID

我有一个客户的非二叉树,我需要为给定节点获取树中的所有 ID。

该表非常简单,只是一个带有父ID和子ID的连接表。这是我存储在数据库中的树的表示。

在此处输入图片说明

在这个例子中,如果我搜索节点 17,我需要返回 14-17。如果我搜索 11,我需要返回 1-6-5-4-8-11-12-7-2-10-3。

顺序并不重要。在将子节点添加到节点时,我只需要 ID 以避免循环。

我创建了这个查询。祖先部分工作正常,我检索了所有父节点,但对于后代我有一些麻烦。我只能检索树的某些部分。例如,对于节点 11,我检索 4-10-6-11-7-8,因此树的所有正确部分都丢失了。

WITH RECURSIVE
-- starting node(s)
starting (parent, child) AS
(
  SELECT t.parent, t.child
  FROM public.customerincustomer AS t
  WHERE t.child = :node or t.parent = :node
)
,
ancestors (parent, child) AS
(
  SELECT t.parent, t.child
  FROM public.customerincustomer AS t
  WHERE t.parent IN (SELECT parent FROM starting)
  UNION ALL
  SELECT t.parent, t.child
  FROM public.customerincustomer AS t JOIN ancestors AS a ON t.child = a.parent
),
descendants (parent, …
Run Code Online (Sandbox Code Playgroud)

postgresql tree recursive

5
推荐指数
2
解决办法
3637
查看次数

按重叠数组分组,可传递,无重复

我发现:

但是,我无法将其用于我的案例。

我有一个像这样的表(实际myid值是散列,但为了说明在这里简化了):

create temp table a (myid text, ip inet);
insert into a (myid, ip)
values
  ('0a', '10.10.1.1'),
  ('0a', '10.10.1.2'),
  ('0a', '10.10.1.3'),
  ('0b', '10.10.1.2'),
  ('0b', '10.10.1.4'),
  ('0c', '10.10.1.5'),
  ('0d', '10.10.1.3'),
  ('0e', '10.10.1.6'),
  ('0e', '10.10.1.7'),
  ('0f', '10.10.1.8'),
  ('0f', '10.10.1.9'),
  ('10', '10.10.1.9'),
  ('11', '10.10.1.10'),
  ('12', '10.10.1.11'),
  ('12', '10.10.1.4'),
  ('1a', '10.10.1.2'),
  ('1a', '10.10.1.4'),
  ('1e', '10.10.1.11'),
  ('1f', '10.10.1.12'),
  ('23', '10.10.1.12');
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何产生的结果是:

         ids         |                         ips
---------------------+------------------------------------------------------
 {0a,0b,0d,12,1a,1e} | {10.10.1.1,10.10.1.2,10.10.1.3,10.10.1.4,10.10.1.11}
 {0c}                | {10.10.1.5}
 {0e}                | {10.10.1.6,10.10.1.7}
 {0f,10}             | {10.10.1.8,10.10.1.9}
 {11}                | …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate array recursive

5
推荐指数
1
解决办法
96
查看次数

基于函数值的递归 CTE 在 Postgres 12 上明显慢于 11

跟进我关于 Postgres 12 中的某些查询比 11 中的查询慢的问题,我认为我能够缩小问题的范围。似乎基于函数值的递归 CTE 是有问题的地方。

我能够分离出一个相当小的 SQL 查询,它在 Postgres 12.1 上运行的时间比在 Postgres 11.6 上运行的时间要长得多,例如 Postgres 12.1 中的大约 150 毫秒与 Postgres 11.6 中的大约 4 毫秒。我能够在各种系统上重现这种现象:在 VirtualBox 中的多个 VM 上;通过两台不同物理机器上的 Docker。(有关 docker 命令,请参阅附录)。然而,奇怪的是,我无法在https://www.db-fiddle.com/上重现它(在那里看不到区别,两者都很快)。

现在进行查询。首先,我们创建这个简单的函数

CREATE OR REPLACE FUNCTION public.my_test_function()
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE SECURITY DEFINER
AS $function$ 

SELECT 
        1::integer AS id,
        '2019-11-20'::date AS "startDate",
        '2020-01-01'::date AS "endDate"

$function$;
Run Code Online (Sandbox Code Playgroud)

然后对于实际查询

WITH  "somePeriods" AS  (
      SELECT * FROM my_test_function() AS 
      f(id integer, "startDate" date, "endDate" …
Run Code Online (Sandbox Code Playgroud)

postgresql cte recursive postgresql-12 postgresql-performance

5
推荐指数
1
解决办法
1639
查看次数

通过自连接表递归获取树

使用此处的其他问题和 Postgresql 文档,我设法构建了一个多对多自联接表。

但是添加一个WHERE条款给我带来了麻烦。

问题:

ACategory可以有许多子类别和许多父类别。给定 a category.Id,我想检索类别、类别儿童、儿童的儿童等。

示例:给定这个结构:

child_1
    child_11
        child_111
        child_112
            child_1121
    child_21
child_2
Run Code Online (Sandbox Code Playgroud)

给定:一个子句 id = child_11

预期结果: child_11, child_111, child_112, child_1121

实际结果: child_11, child_111, child_112

这是我的尝试:http : //sqlfiddle.com/#!17/3640f/2

如果 Sqlfiddle 关闭:https ://www.db-fiddle.com/#&togetherjs=LhDjxfPHo6

注意:我不在乎复制 where 子句,我的应用程序可以处理

表结构:

CREATE TABLE Category(id SERIAL PRIMARY KEY, name VARCHAR(255));
CREATE TABLE Categories(parent_id INTEGER, child_id INTEGER, PRIMARY KEY(parent_id, child_id));

ALTER TABLE Categories ADD FOREIGN KEY (parent_id) REFERENCES category (id);
ALTER TABLE Categories ADD …
Run Code Online (Sandbox Code Playgroud)

postgresql recursive many-to-many self-join

5
推荐指数
1
解决办法
175
查看次数

无法找到祖先的 CTE 查询

我有一张桌子 foo

桌子

与内容

在此处输入图片说明

所以表 foo 的记录可以用这个图形来表示。

在此处输入图片说明

当我运行一个应该使用@starting_id=9 返回祖先的过程时

(在图中用圆圈表示),我得到这个结果

  • 9

代替

  • 9
  • 3 和
  • 1

为什么?

CREATE PROCEDURE [dbo].[GetParents]
    @starting_id int
AS
BEGIN
    WITH chainIDsUpwards AS
    (
        SELECT id, parent_id FROM foo WHERE id = @starting_id

        UNION ALL

        SELECT foo.id, foo.parent_id FROM foo
        JOIN chainIDsUpwards p ON p.id = foo.parent_id
    )

    SELECT id FROM chainIDsUpwards
END
Run Code Online (Sandbox Code Playgroud)

小提琴在https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=81be3d86dc7581eb60bc7af4c09077e4

sql-server cte t-sql recursive

5
推荐指数
1
解决办法
177
查看次数

使用 PostgreSQL 确定网络中的节点

我有一个表,其中每个条目都是一个节点,该表包含每个节点到其他节点的直接连接。我希望为每个节点创建一个包含链中所有节点的列的视图,而不仅仅是节点本身所连接的节点。

一个示例是从下表的前两列生成链中的节点列:

CREATE TABLE example
(
    node text,
    connections text[],
    nodes_in_chain text[]
)

INSERT INTO example VALUES
('a', ARRAY['a','b'],         null),
('b', ARRAY['a','b','c','d'], null),
('c', ARRAY['b','c'],         null),
('d', ARRAY['b','d'],         null),
('e', ARRAY['e','f'],         null),
('f', ARRAY['e','f'],         null);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE example
(
    node text,
    connections text[],
    nodes_in_chain text[]
)

INSERT INTO example VALUES
('a', ARRAY['a','b'],         null),
('b', ARRAY['a','b','c','d'], null),
('c', ARRAY['b','c'],         null),
('d', ARRAY['b','d'],         null),
('e', ARRAY['e','f'],         null),
('f', ARRAY['e','f'],         null);
Run Code Online (Sandbox Code Playgroud)

这是实际问题的一个小型简化版本。如果我能解决这个例子,全表应该没问题。

该表的数据可以通过以下方式进行可视化:

数据

我研究了几种不同的方法来解决这个问题。我已经研究了递归 CTE,但我还没有设法让它们工作。

每个节点都连接到当前在数据库中的自身。如果有必要,在数据库中删除与自身的连接不是问题。

可能不必要的问题背景

这个问题的根源来自于试图识别交通中的车辆。原始数据库包含给定区域内每个时间步长 t 的车辆位置和速度。目标是确定在红绿灯处花费的时间。为了解决这个问题,确定了交通灯的停车区域。该区域内速度低于特定阈值的每辆车都被认为正在等待红绿灯。由于排队时间较长,车辆可能会在该区域外排队。因此,一条交通线(“节点链”)由彼此相距一定距离内的所有车辆组成,并且在其下方具有低速。从识别的排队区域内的车辆出发。这个问题是飞机滑行时间科学研究的一部分。

我首先使用 Python …

postgresql recursive postgresql-11

5
推荐指数
1
解决办法
114
查看次数

进行类似查询的递归 CTE,但对于许多记录

我有一个带有层次结构的表(带有递归 parentID 列),对于一个记录,我知道如何使用以下代码获取最后一个父记录:

declare @Id integer

;WITH CTE AS
(
    SELECT  a.[Id],
            a.[ParentId]
    FROM    [Area] a WITH (NOLOCK)
    where a.[Id] = @Id 

    UNION ALL

    SELECT  a.[Id],
            a.[ParentId]
    FROM [Area] a WITH (NOLOCK)
    INNER JOIN CTE cte ON cte.[ParentId] = a.[Id]
)

SELECT top 1 a.[Id]
FROM CTE a
WHERE a.ParentId is null
Run Code Online (Sandbox Code Playgroud)

只要我使用一个 id 就可以工作,这里是 @Id。

但是我找不到一种方法来做同样的事情,但对于 Id 列表,不使用游标,因为 CTE 似乎只有在您处理一条记录时才可以。

有人能指出我正确的方向吗?

非常感谢

sql-server cte recursive

4
推荐指数
1
解决办法
4827
查看次数

为什么递归 CTE 估计只有 1 行?

给定两个级联的、独立的(没有真正的表)递归 CTE:

create view NumberSequence_0_100_View
as
with NumberSequence as
(
    select 0 as Number
    union all
    select Number + 1
      from NumberSequence    
     where Number < 100
)
select Number
  from NumberSequence;
go

create view NumberSequence_0_10000_View
as
select top 10001
       v100.Number * 100 + v1.Number as Number
  from Common.NumberSequence_0_100_View v100
 cross join Common.NumberSequence_0_100_View v1
 where v1.Number < 100
   and v100.Number * 100 + v1.Number <= 10000
    -- please resist complaining about "order by in view" for this question
 order by v100.Number …
Run Code Online (Sandbox Code Playgroud)

sql-server cte sql-server-2012 recursive cardinality-estimates

4
推荐指数
1
解决办法
780
查看次数