我有一个包含层次结构数据的表 - 类似于:
childID | parentID
____________________
1 | 5
5 | 9
9 | 20
2 | 4
3 | 7
7 | 8
8 | 8
20 | 20
4 | 4
8 | 8
Run Code Online (Sandbox Code Playgroud)
期望的输出:

我创建了一个递归CTE,它找到了我的顶部fatherID.
就像是:
;WITH cte AS (
SELECT a.childID
,a.parentID
,1 AS lvl
FROM [Agent_Agents] a
WHERE a.childID = 214 //<==== value to begin with !! - thats part the problem
UNION ALL
SELECT tmp.childID
,tmp.parentID
,cte.lvl+1
FROM [Agent_Agents] tmp
INNER …Run Code Online (Sandbox Code Playgroud) 我在这里搜索过这个问题,但找不到它,如果我们已经在网站上有它,请重定向我.
我正在寻找一种方法来创建CTE,它使用另一个CTE作为进一步限制的数据.我有一个CTE,它为我创建了一个报告,但我希望使用现有的CTE以另一个输入来缩小此报告.
我希望我的问题很明确.
我在SQL Server数据库中使用了一组分层数据.数据以guid作为主键存储,而parentGuid作为指向直接父对象的外键存储.我最常通过WebApi项目中的Entity Framework访问数据.为了使情况更复杂,我还需要基于此层次结构管理权限,以便应用于父级的权限适用于其所有后代.我的问题是:
我已经搜遍了所有,无法决定哪种方法最适合处理这种情况.我知道我有以下选择.
Recursive CTEsCommon Table Expression(也就是RCTE)来处理分层数据.这似乎是正常访问最简单的方法,但我担心在用于确定子对象的权限级别时可能会很慢.hierarchyId表中,并使用SQL Server所提供的功能,如数据类型字段GetAncestor(),IsDescendantOf()和等,这似乎将让查询很容易,但似乎需要一个相当复杂的插入/更新触发器,以保持HIERARCHYID域是正确的通过插入和移动closure table,它将存储表中的所有关系.我想象如下:父列和子列,每个父 - >子关系将被表示.(即1-> 2 2-> 3将在数据库中表示为1-2,1-3,2-3).缺点是这需要插入,更新和删除触发器,即使它们非常简单,并且此方法会生成大量记录.我已经尝试过全面搜索,但在这三种方法之间找不到任何建议.
PS我也对这个问题的任何替代解决方案持开放态度
sql-server recursive-query common-table-expression hierarchyid transitive-closure-table
我有两个Query,Query1:
with cte as (
select
dbo.Cable.*,
row_number() over(partition by dbo.Cable.TagNo order by dbo.Cable.CableRevision desc) as rn
from dbo.Cable
where (dbo.Cable.CableRevision = @CoreRevision )
)
select *
from cte
where rn = 1
Run Code Online (Sandbox Code Playgroud)
还有Query2
with cte as (
select
dbo.Cable.TagNo,dbo.Core.*,
row_number() over(partition by dbo.Core.CoreNo order by dbo.Core.CoreRevision desc) as rn
from dbo.Core INNER JOIN
dbo.Cable ON dbo.Cable.Id = dbo.Core.CableId
where (dbo.Core.CoreRevision <= @CoreRevision )
)
select *
from cte
where rn = 1
Run Code Online (Sandbox Code Playgroud)
这两个查询是相关的Query1.TagNo,Query2.TagNo
如何使用加入这两个查询,是否可以使用WithCommand …
WITH DTL AS
(SELECT CMPI_CODE,
CMN_CDTY_MTRL,
CMI_WT_FACTOR,
CMI_CNTRCT_RATE,
'PL',
PRESENT_PRICE,
TRM_CODE,
ROUND(((NVL(PRESENT_PRICE,1)*CMI_WT_FACTOR) / CMI_CNTRCT_RATE),2) AS PL_FACTOR
FROM VW_CMD_MATERIAL WHERE TRM_CODE = 41)
INSERT iNTO IPA_PRCADJ_HDR(TRM_CODE,IPAPH_ADJ_FACTOR,IPAPH_AMT_CUR,IPAPH_REMARKS)
SELECT TRM_CODE,SUM(PL_FACTOR) AS PL_FACTOR,((SUM(PL_FACTOR)*10)) AS AMT_CUR,'asdf'
FROM DTL GROUP BY (TRM_CODE);
Run Code Online (Sandbox Code Playgroud)
显示错误 ORA-00928: missing SELECT keyword
我使用PostgreSQL 9.1来查询分层树结构数据,包括与节点连接的边(或元素).数据实际上是用于流网络,但我已经将问题抽象为简单的数据类型.考虑示例tree表.每条边都有长度和面积属性,用于确定网络中的一些有用指标.
CREATE TEMP TABLE tree (
edge text PRIMARY KEY,
from_node integer UNIQUE NOT NULL, -- can also act as PK
to_node integer REFERENCES tree (from_node),
mode character varying(5), -- redundant, but illustrative
length numeric NOT NULL,
area numeric NOT NULL,
fwd_path text[], -- optional ordered sequence, useful for debugging
fwd_search_depth integer,
fwd_length numeric,
rev_path text[], -- optional unordered set, useful for debugging
rev_search_depth integer,
rev_length numeric,
rev_area numeric
);
CREATE INDEX ON tree (to_node);
INSERT INTO …Run Code Online (Sandbox Code Playgroud) postgresql recursive-query common-table-expression hierarchical-query transitive-closure-table
根据Redshift WITH Clause 文档,您可以将WITH子句与INSERT INTO...SELECT语句一起使用.但是在测试时,我收到以下错误.这是不可能的,还是我的语法错了?
CREATE TABLE TestCTEInsert (SomeTimestamp TIMESTAMP);
WITH CTE AS
(SELECT GETDATE() as SomeTimestamp)
INSERT INTO TestCTEInsert
(SomeTimestamp) SELECT SomeTimestamp from CTE;
Run Code Online (Sandbox Code Playgroud)
错误:42601:"插入"或附近的语法错误
有趣的是,它确实支持插入新表,即
WITH CTE AS
(SELECT GETDATE() as SomeTimestamp)
INSERT SomeTimestamp INTO NewTable
SELECT SomeTimestamp from CTE;
Run Code Online (Sandbox Code Playgroud)
命令成功完成(受影响的1行)
编辑:只是为了确认,我在使用INTEGER列而不是TIMESTAMP:时得到相同的错误:
CREATE TABLE TestCTE (SomeInt INTEGER);
WITH CTE AS
(SELECT 1 as SomeInt)
INSERT INTO TestCTEInsert
SELECT SomeInt from CTE;
Run Code Online (Sandbox Code Playgroud)
错误:42601:"插入"或附近的语法错误
sql common-table-expression amazon-web-services amazon-redshift
它看起来有点滑稽,但Oracle 11g确实允许这样的查询运行
with
a as (select 1 from dual),
a as (select 2 from dual)
select *
from a;
Run Code Online (Sandbox Code Playgroud)
它返回第一个子查询的结果(即1).
我无法想象这种特征可能有用的情况.在我的情况下,当我忘记在复制/粘贴它后重命名子查询并且整个查询返回错误/意外结果时,它会引起问题.幸运的是,查询非常简单,并且立即检测到了原因.
无论如何,我希望Oracle在这种情况下抛出异常.
所以,我的问题是这样的行为是特征还是错误?如果功能,它可能有用吗?
谢谢.
顺便说一句,SQLite不允许类似的查询运行并抛出'重复的WITh表名'异常.还没试过任何其他数据库引擎.
我可以在分层数据模型中找到给定记录的所有子项(请参阅下面的代码),但我不确定如何遍历具有给定子ID的父/子链.任何人都可以指出我正确的方向来弄清楚如何做到这一点?这对Linq to SQL也有可能吗?
WITH TaskHierarchy (TaskID, [Subject], ParentID, HierarchyLevel, HierarchyPath) AS
(
-- Base case
SELECT
TaskID,
[Subject],
ParentID,
1 as HierarchyLevel,
CONVERT(VARCHAR(MAX),'/') AS HierarchyPath
FROM Task
WHERE TaskID = 2
UNION ALL
-- Recursive step
SELECT
t.TaskID,
t.Subject,
t.ParentID,
th.HierarchyLevel + 1 AS HierarchyLevel,
CONVERT(varchar(MAX),th.HierarchyPath + CONVERT(VARCHAR(32),t.ParentID) + '/') AS HierarchyPath
FROM Task t
INNER JOIN TaskHierarchy th ON
t.ParentID = th.TaskID
)
SELECT *
FROM TaskHierarchy
ORDER BY HierarchyLevel, [Subject]
Run Code Online (Sandbox Code Playgroud) 我理解如何使用该WITH子句进行递归查询(!!),但我在理解它的一般用途/能力方面遇到了问题.
例如,以下查询更新一条记录,其id通过使用子查询确定,该子查询按时间戳返回第一条记录的id:
update global.prospect psp
set status=status||'*'
where psp.psp_id=(
select p2.psp_id
from global.prospect p2
where p2.status='new' or p2.status='reset'
order by p2.request_ts
limit 1 )
returning psp.*;
Run Code Online (Sandbox Code Playgroud)
这是否适合使用WITH包装器而不是相对丑陋的子查询?如果是这样,为什么?
sql ×7
oracle ×2
postgresql ×2
sql-server ×2
t-sql ×2
hierarchy ×1
hierarchyid ×1
linq-to-sql ×1
oracle11g ×1
sql-update ×1