我有一个包含两列的表,Parent并且Child.
我需要获取与父记录关联的所有后代的列表。
Source Table
+----+-----------+
| Parent | Child |
+----+-----------+
| a | b |
| b | c |
| c | d |
| d | e |
| e | f |
| f | x |
+----+-----------+
Expected Result:
+----+-----------+
| Parent | Child |
+----+-----------+
| a | b | // As b is the child of a, all the descendants of b
| a | c | // are …Run Code Online (Sandbox Code Playgroud) 我正在尝试提出一个递归 CTE 和/或窗口函数来创建一个函数。
几天后,我将函数归结为(伪代码),我拥有N和B,并且需要生成E:
E n = B n * (1 - SUM( E 1 , E 2 , ... E n-1 ))
?????????????????????????????????
? N ? B ? E ?
?????????????????????????????????
? 0 ? 0.142857143 ? 0.142857143 ?
? 1 ? 0.285714286 ? 0.244897959 ?
? 2 ? 0.285714286 ? 0.174927114 ?
? 3 ? 0.285714286 ? 0.124947938 ?
? 4 ? 0.285714286 ? 0.089248527 ?
? 5 ? 0.4 ? 0.089248527 …Run Code Online (Sandbox Code Playgroud) 给定一个 SourceTable 和一个 TargetTable,我想以编程方式创建一个需要所有连接的字符串。
简而言之,我试图找到一种方法来创建这样的字符串:
FROM SourceTable t
JOIN IntermediateTable t1 on t1.keycolumn = t.keycolumn
JOIN TargetTable t2 on t2.keycolumn = t1.keycolumn
Run Code Online (Sandbox Code Playgroud)
我有一个查询返回给定表的所有外键,但是在尝试递归运行所有这些以找到最佳连接路径并生成字符串时遇到了限制。
SELECT
p.name AS ParentTable
,pc.name AS ParentColumn
,r.name AS ChildTable
,rc.name AS ChildColumn
FROM sys.foreign_key_columns fk
JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id
JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id
JOIN sys.tables p ON p.object_id = fk.parent_object_id
JOIN sys.tables r ON r.object_id = fk.referenced_object_id
WHERE fk.parent_object_id = OBJECT_ID('aTable')
ORDER …Run Code Online (Sandbox Code Playgroud) 我在树结构上使用递归 CTE 来列出树中特定节点的所有后代。如果我在我的WHERE子句中写了一个文字节点值,SQL Server 似乎实际上只是将 CTE 应用于该值,给出一个实际行数较低的查询计划,等等:
但是,如果我将该值作为参数传递,它似乎实现了(假脱机)CTE,然后在事后对其进行过滤:
我可能读错了计划。我没有注意到性能问题,但我担心 CTE 的实现可能会导致较大数据集出现问题,尤其是在繁忙的系统中。此外,我通常将这种遍历本身复合:我遍历祖先并返回后代(以确保收集所有相关节点)。由于我的数据如何,每组“相关”节点都相当小,因此实现 CTE 没有意义。当 SQL Server 似乎意识到 CTE 时,它在“实际”计数中给了我一些相当大的数字。
有没有办法让查询的参数化版本表现得像文字版本?我想把 CTE 放在一个可重用的视图中。
用文字查询:
CREATE PROCEDURE #c AS BEGIN;
WITH descendants AS (SELECT
t.ParentId Id
,t.Id DescendantId
FROM #tree t
WHERE t.ParentId IS NOT NULL
UNION ALL SELECT
d.Id
,t.Id DescendantId
FROM descendants d
JOIN #tree t ON d.DescendantId = t.ParentId)
SELECT d.*
FROM descendants d
WHERE d.Id = 24
ORDER BY d.Id, d.DescendantId; …Run Code Online (Sandbox Code Playgroud) 需要有关递归 CTE 性能的帮助。低于 CTE 的运行速度非常慢,因为它试图以递归方式提取分层数据。表很大,每个根 ID 最多有 3 个递归 itemid。可能有大约 200000 个或更多的 root id。我知道递归 CTE 对于庞大的数据集来说很慢,因为对于锚点中的每个 rootid,它都会递归地进行 itemid。
架构:
Create table RootItem (ItemId int primary key, RootIt int , insertdate datetime)
Run Code Online (Sandbox Code Playgroud)
上表有超过 100 万行。
CTE 查询:
; With rootcte as
( select itemid from RootItem where rootid is null
union all
select r.itemid as RootId , i.itemid from RootItem i join rootcte r
on i.rootid = r.itemid
)
Run Code Online (Sandbox Code Playgroud)
我们无法修改表架构并使用层次结构。我也试过 while 循环,但这也很慢。
有没有其他方法可以优化此查询?
; With rootcte as
( select itemid from …Run Code Online (Sandbox Code Playgroud) 我有桌子currency_pair(c1, c2);值是(usd,bnb), (cake,bnb), (cake,eth)。
我需要找到一个让我比较的最短路径usd来eth。
此处的结果将是相同的值。然后我可以使用第一对建立一个 usd-bnb 关系,然后我可以用它来计算 usd-cake 关系,然后我可以用它来计算 usd-eth。
由于顺序是不确定的,我做的第一步是创建一个物化视图,currency_pair_map(c1, c2),它是 的并集select c1, c2 union select c2, c1。这似乎简化了逻辑。
如果我正确考虑这一点,我需要做的是使用WITH RECURSIVE?我还应该有某种“depth_limit”参数,以确保在无法建立一对时查询失败。
大声思考这个问题,我们应该始终从以下几点开始:
SELECT *
FROM currency_pair
WHERE
c1 = 'usd' AND
c2 = 'eth'
Run Code Online (Sandbox Code Playgroud)
如果有结果,我们应该到此为止。
如果没有,那么我们需要找到所有usd-*对并继续搜索,直到找到以 结尾的对eth。
使用这个逻辑,到目前为止我有:
WITH RECURSIVE pair_route AS (
SELECT
1 depth,
cp1.id,
cp1.c1,
cp1.c2
FROM currency_pair cp1
WHERE
cp1.c1 = 'usd'
UNION
SELECT
pr1.depth + 1, …Run Code Online (Sandbox Code Playgroud) TL;博士; SQL Server 允许标量 UDF 在架构绑定时递归调用自身,但仅在使用语法进行更改时才这样做,这是否是一个错误CREATE OR ALTER?或者是其他语法被禁止的错误?
一个简单的递归标量 UDF 可以构造如下
CREATE FUNCTION dbo.Try1 (@i int)
RETURNS int
AS BEGIN
RETURN IIF(@i = 0, 0, @i + dbo.Try1(@i - 1));
END;
Run Code Online (Sandbox Code Playgroud)
只要这不是架构绑定的,那么这是允许的。
让我们尝试模式绑定它,我们会做
CREATE FUNCTION dbo.Try2 (@i int)
RETURNS int
WITH SCHEMABINDING
AS BEGIN
RETURN IIF(@i = 0, 0, @i + dbo.Try2(@i - 1));
END;
Run Code Online (Sandbox Code Playgroud)
没有。
Cannot find either column "dbo" or the user-defined function
or aggregate "dbo.Try2", or the name is ambiguous
Run Code Online (Sandbox Code Playgroud)
不使用递归创建它然后更改它
CREATE OR ALTER …Run Code Online (Sandbox Code Playgroud) 我有一些体现有向无环图的关系,其中包括类似于以下内容的模式:
我正在寻找一种有效的方法来遍历此图形数据。下面是计算节点 0 的后代的看似简单任务的示例:
DROP TABLE IF EXISTS #edges;
CREATE TABLE #edges(tail int, head int);
INSERT INTO #edges(tail,head) VALUES
(0,1), (5, 6), (10,11), (15,16),
(0,2), (5, 7), (10,12), (15,17),
(1,2), (6, 7), (11,12), (16,17),
(1,3), (7, 8), (11,13), (17,18),
(2,3), (7, 9), (12,13), (17,19),
(2,4), (8, 9), (12,14), (18,19),
(3,4), (8,10), (13,14),
(3,5), (9,10), (13,15),
(4,5), (9,11), (14,15),
(4,6), (14,16);
WITH descendents(node)
AS(
SELECT 0 as node
UNION ALL
SELECT head as node FROM descendents as prior
JOIN #edges …Run Code Online (Sandbox Code Playgroud) 我有一个文章表,我希望 slug 是独一无二的。
CREATE TABLE article (
title char(50) NOT NULL,
slug char(50) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
当用户输入标题时,例如News on Apple,我想检查数据库以查看是否存在相应的 slug,例如news-on-apple。如果是这样,我将给一个数值添加后缀,直到找到一个唯一的值,例如news-on-apple-1. 可以通过递归 CTE 查询而不是在我的 ORM 中进行递归来实现。是否有一个很好的大概数字,我应该停止递归和出错。我可以想象人们使用相同的标题 1000 次,这将导致 1000 次查询只是为了创建 1 篇文章。
我对递归 CTE 的理解可能是不正确的,并且没有更好的方法来找到唯一的 slug。请提出任何替代方案。
实际查询更多,但我面临的问题可以归结为:
用于过滤单调递增整数行集的查询,以便 -在最终结果集中, row(n+1).value >= row(n).value + 5。
对于我需要解决的实际问题,行集计数在 1000 秒内。
举几个例子来澄清:
我设法通过以下查询获得了所需的结果,但它似乎过于复杂。取消注释不同的“..with t(k)..”以尝试它们。
我正在寻找任何简化或替代方法来获得相同的结果。
with recursive r(n, pri) as (
with t(k) as (values (1),(2),(3),(4),(5)) -- the data we want to filter
-- with t(k) as (values (1),(5),(7),(10),(11),(12),(13))
-- with t(k) as (values (6),(8),(11),(16),(20),(23))
-- with t(k) as (values (6),(8),(12),(16),(20),(23))
select min(k), 1::bigint from t -- bootstrap for recursive processing. 1 here represents rank().
UNION
select k, (rank() over(order …Run Code Online (Sandbox Code Playgroud) recursive ×10
cte ×6
sql-server ×5
postgresql ×3
performance ×2
functions ×1
graph ×1
optimization ×1
t-sql ×1