标签: common-table-expression

存储/访问有向图的最佳方式

我有大约3500个防洪设施,我想将其表示为确定流路径的网络(基本上是有向图).我目前正在使用SqlServer和CTE递归检查所有节点及其上游组件,只要上游路径不分叉,这就可以工作.然而,由于增加了上游复杂性,一些查询比其他查询指数长得多,即使它们在物理上不太远(即两个或三个"下游"段).在某些情况下,我会在杀死查询之前让它超过十分钟.我正在使用一个简单的双列表,一列是设施本身,另一列是第一列中列出的设施的上游设施.

我尝试使用当前工具添加索引以帮助加快速度,但这没有任何区别.并且,对于图中可能的连接,任何节点可以具有多个上游连接,并且可以从多个"下游"节点连接.

当然有可能在数据中有循环,但我还没有找到一种好的方法来验证这一点(除了CTE查询报告最大递归计数命中时;这些很容易修复).

所以,我的问题是,我存储这些信息是错误的吗?有没有比CTE更好的方法来查询上游点?

rdbms directed-graph common-table-expression

12
推荐指数
2
解决办法
4254
查看次数

Linq中的分层数据 - 选项和性能

我有一些分层数据 - 每个条目都有一个id和一个(可空)父条目id.我想检索给定条目下树中的所有条目.这是在SQL Server 2005数据库中.我在C#3.5中使用LINQ to SQL查询它.

LINQ to SQL不直接支持公用表表达式.我的选择是使用几个LINQ查询在代码中汇编数据,或者在面向CTE的数据库上进行查看.

当数据量变大时,您认为哪个选项(或其他选项)会表现更好?Linq to SQL是否支持SQL Server 2008的HierarchyId类型

sql linq sql-server-2005 common-table-expression c#-3.0

12
推荐指数
3
解决办法
2万
查看次数

SQL Server:如何将CTE递归限制为只是递归添加的行?

更简单的例子

让我们尝试一个更简单的例子,这样人们可以围绕这些概念,并有一个实际的例子,你可以复制并粘贴到SQL Query Analizer:

想象一个具有层次结构的节点表:

A
 - B
    - C
Run Code Online (Sandbox Code Playgroud)

我们可以在Query Analizer中开始测试:

CREATE TABLE ##Nodes
(
 NodeID varchar(50) PRIMARY KEY NOT NULL,
 ParentNodeID varchar(50) NULL
)

INSERT INTO ##Nodes (NodeID, ParentNodeID) VALUES ('A', null)
INSERT INTO ##Nodes (NodeID, ParentNodeID) VALUES ('B', 'A')
INSERT INTO ##Nodes (NodeID, ParentNodeID) VALUES ('C', 'B')
Run Code Online (Sandbox Code Playgroud)

期望的输出:

ParentNodeID    NodeID    GenerationsRemoved
============    ======    ==================
NULL            A         1
NULL            B         2
NULL            C         3
A               B         1
A               C         2
B               C         1
Run Code Online (Sandbox Code Playgroud)

现在建议的CTE表达式,输出不正确:

WITH NodeChildren …
Run Code Online (Sandbox Code Playgroud)

sql-server common-table-expression

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

sql server中公用表表达式的优点是什么

我们写下一个CTE sql

WITH yourCTE AS 
(
 SELECT .... FROM :... WHERE.....
) SELECT * FROM yourCTE
Run Code Online (Sandbox Code Playgroud)

将sql放入块中会有什么好处.我认为,如果我们把复杂的sql放入块中,那么我们就可以编写像sql一样的了SELECT * FROM yourCTE.好像我正在访问视图.在性能方面使用CTE的附加优势是什么.请讨论.谢谢

sql t-sql sql-server common-table-expression

12
推荐指数
2
解决办法
3万
查看次数

为什么递归CTE在程序上运行分析函数(ROW_NUMBER)?

我昨天回答了一个递归的CTE,它揭示了这些在SQL Server中实现的方式的问题(也可能在其他RDBMS中?).基本上,当我尝试使用ROW_NUMBER当前的递归级别时,它会针对当前递归级别的每个行子集运行.我希望这可以在真正的SET逻​​辑中工作,并针对整个当前的递归级别运行.

看来,从这篇MSDN文章中,我发现的问题是预期的功能:

CTE的递归部分中的分析和聚合函数应用于当前递归级别的集合,而不应用于CTE的集合.像ROW_NUMBER这样的函数只对当前递归级别传递给它们的数据子集起作用,而不是对整个CTE递归部分的数据集合起作用.有关更多信息,请参阅J.在递归CTE中使用分析函数.

在我的挖掘中,我找不到解释为什么选择这样做的方式呢?这在基于集合的语言中更像是一种过程方法,因此这对我的SQL思维过程起作用,在我看来非常混乱.是否有人知道和/或可以解释为什么递归CTE以递归方式处理递归级别的分析函数?


以下是帮助可视化的代码:

请注意,RowNumber每个代码输出中的列.

这是CTE的SQLFiddle(仅显示递归的第二级)

WITH myCTE
AS
(
  SELECT *, ROW_NUMBER() OVER (ORDER BY Score desc) AS RowNumber, 1 AS RecurseLevel
  FROM tblGroups
  WHERE ParentId IS NULL

  UNION ALL

  SELECT tblGroups.*, 
      ROW_NUMBER() OVER (ORDER BY myCTE.RowNumber , tblGroups.Score desc) AS RowNumber, 
      RecurseLevel + 1 AS RecurseLevel
  FROM tblGroups
      JOIN myCTE
          ON myCTE.GroupID = tblGroups.ParentID
 )
SELECT *
FROM myCTE
WHERE RecurseLevel = 2; …
Run Code Online (Sandbox Code Playgroud)

sql sql-server row-number common-table-expression recursive-cte

12
推荐指数
1
解决办法
1797
查看次数

CTE获取父母的所有孩子(后代)

我有这个让我头疼的问题......

说,我有一个包含数千行的表,表的结构包含父 - >子关系.

这种关系可以达到6个级别.这是表结构的示例:

ProductId | ParentId | Levels
1174           0        1174
311           1174      311, 1174
1186          311       1186, 311, 1174
448           1186      448, 1186, 311, 1174
3365          448       3365, 448, 1186, 311, 1174
Run Code Online (Sandbox Code Playgroud)

我们有一个循环遍历整个表以获取关系并保存"级别"列的进程,这个过程非常慢(因为循环)并且我尝试了一些cte来获得关系,但是很难实现.

到目前为止,我已经尝试过这个cte,但它没有做我希望的事情,而且,它似乎在复制行...

;With Parents(ProductId, ParentId, Levels)
As(
  Select ProductId, ParentId, Levels
  From Products
  Where ParentId = 0 
  Union All
  Select p.ProductId, p.ParentId, p.Levels
  From Products p
  Join Parents cte On cte.ProductId = p.ParentId
)
Select *
From Parents
Run Code Online (Sandbox Code Playgroud)

正如我之前提到的,我们有一个循环表的过程,它完成它的工作,但它可能需要长达30分钟,我的问题是有更好的方法来做到这一点?我知道CTE允许我这样做,但我很糟糕,同样,应该在桌面上计算和更新关卡列,是否可能?

这是一个Sqlfiddle以防有人可以提供帮助,谢谢!

sql-server common-table-expression

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

在CTE中构建已定义值的列表

有没有办法为硬编码值列表构建CTE?例如,我有一个已知ID的列表(即101,102,105,200 ...),我如何能够创建一个名为ID的列的CTE,但所有ID值在查询中都是硬编码的?顺便说一句,我需要在Oracle中运行此查询.谢谢!

sql oracle common-table-expression

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

SQL - CTE与VIEW

我在这里的问题是,是什么区别CTEViewSQL.我的意思是在哪种情况下我应该使用CTE和哪种情况View.我知道两者都是某种虚拟表,但我不能区分它们的用途.

我在这里发现了一个类似的问题,但它是关于性能的.

更新1:

例如:我有一个填充了trades(tbl_trade)的数据库.我需要从3.5百万条记录中选择当前时间到当前时间打开的交易然后操纵数据(在虚拟表上使用不同的查询 - 这看起来像View).这里的问题是我想要一个SUM3-4列,然后我需要SUM一些列并创建一个带有结果的虚拟列(看起来像CTE).

例如:tbl_trade有列:profit,bonusexpenses.我需要的SUM(profit),SUM(bonus),SUM(expenses)和新的一列total,这将是等于SUM(profit)+ SUM(bonus)+ SUM(expenses).

PS.重新运行查询SUM不是一个选项,因为我已经有了结果.

提前致谢!

sql sql-server common-table-expression sql-view

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

删除重复的子查询

我有一个复杂的SQL查询,可以简化到下面:

Select ColA,ColB,ColC,ColD
From MyTable
Where (ColA In (Select ItemID From Items Where ItemName like '%xxx%') 
    or ColB In (Select ItemID From Items Where ItemName like '%xxx%'))
Run Code Online (Sandbox Code Playgroud)

如您所见,子查询出现两次.编译器是否足够智能来检测它并仅获取子查询的结果一次?或者子查询运行两次?

仅供参考,表项目大约有20,000行,MyTable有大约200,000行.

是否有另一种方法来重写此SQL语句,以便子查询只出现/运行一次?

更新:主查询中的Where子句是动态的,仅在需要时添加(即仅在用户搜索"xxx"时).因此,不可能对主select语句进行更改或重新构造查询.

sql t-sql sql-server dynamic-sql common-table-expression

12
推荐指数
1
解决办法
2155
查看次数

Postgres CTE:非递归项中的类型字符变化(255)[]但整体上类型字符变化[]

我是SO和postgres的新手所以请原谅我的无知.尝试使用类似于本文中的解决方案在postgres中获取图表的集群在PostgreSQL中查找集群给定节点

唯一的区别是我的id是一个UUID,我使用varchar(255)来存储这个id

当我尝试运行查询时,我收到以下错误(但不知道如何投射):

ERROR: recursive query "search_graph" column 1 has type character varying(255)[] in non-recursive term but type character varying[] overall
Run Code Online (Sandbox Code Playgroud)

SQL状态:42804提示:将非递归项的输出强制转换为正确的类型.性格:81

我的代码(与上一篇文章基本相同):

WITH RECURSIVE search_graph(path, last_profile1, last_profile2) AS (
SELECT ARRAY[id], id, id
FROM node WHERE id = '408d6b12-d03e-42c2-a2a7-066b3c060a0b'
UNION ALL
SELECT sg.path || m.toid || m.fromid, m.fromid, m.toid
FROM search_graph sg
JOIN rel m
ON (m.fromid = sg.last_profile2 AND NOT sg.path @> ARRAY[m.toid]) 
   OR (m.toid = sg.last_profile1 AND NOT sg.path @> ARRAY[m.fromid])
)

 SELECT DISTINCT unnest(path) FROM …
Run Code Online (Sandbox Code Playgroud)

postgresql graph-theory common-table-expression

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