我有一张桌子,上面有客户及其联合客户。例如,客户 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) 我有一个大致像这样的架构(这是我实际架构的简化):
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
我有一个客户的非二叉树,我需要为给定节点获取树中的所有 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) 我发现:
但是,我无法将其用于我的案例。
我有一个像这样的表(实际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) 跟进我关于 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
使用此处的其他问题和 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) 我有一张桌子 foo
与内容
所以表 foo 的记录可以用这个图形来表示。
当我运行一个应该使用@starting_id=9 返回祖先的过程时
(在图中用圆圈表示),我得到这个结果
代替
为什么?
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
我有一个表,其中每个条目都是一个节点,该表包含每个节点到其他节点的直接连接。我希望为每个节点创建一个包含链中所有节点的列的视图,而不仅仅是节点本身所连接的节点。
一个示例是从下表的前两列生成链中的节点列:
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 …
我有一个带有层次结构的表(带有递归 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 似乎只有在您处理一条记录时才可以。
有人能指出我正确的方向吗?
非常感谢
给定两个级联的、独立的(没有真正的表)递归 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
recursive ×10
cte ×5
postgresql ×5
sql-server ×5
aggregate ×1
array ×1
many-to-many ×1
performance ×1
self-join ×1
t-sql ×1
tree ×1