CTE(普通表表达式)vs Temp tables或Table variables,哪个更快?
performance temp-tables common-table-expression table-variable sql-server-2008-r2
我在数据库中有每个标识符的以下2条信息.控制它们的公司,以及控制它们的公司.
沿线的东西,2个表(忽略一些唯一标识符):
组织
orgid | org_immediate_parent_orgid
1 | 2
2 | 2
3 | 1
5 | 4
Run Code Online (Sandbox Code Playgroud)
关系orgid - > org_immediate_parent_orgid意味着公司有父母.在我看来它只有相关的org_immediate_parent_orgid - > orgid公司的母公司作为子公司
org_affiliations
orgid | affiliated_orgid
2 | 3
2 | 5
4 | 1
1 | 5
Run Code Online (Sandbox Code Playgroud)
orgid - > affiliated_orgid是公司的附属机构
视觉表示应该是这样的:

关于组织的红色关系,蓝色关系org_affiliations.
如果想让2所有的所有公司(或2的子公司)拥有它们的一部分:
select m.org_immediate_parent_orgid
,m.orgid
from oa.organizations m
where m.org_immediate_parent_orgid is not null
start with m.orgid in (Identifiers)
connect by nocycle prior m.orgid=m.org_immediate_parent_orgid
Run Code Online (Sandbox Code Playgroud)
回报
org_immediate_parent_orgid| orgid
1 | 2
2 …Run Code Online (Sandbox Code Playgroud) 考虑以下
;WITH GetParentOfChild AS
(
SELECT
Rn = ROW_NUMBER() Over(Order By (Select 1))
,row_id AS Parents
,parent_account_id As ParentId
FROM siebelextract..account
WHERE row_id = @ChildId
UNION ALL
SELECT
Rn + 1
,a.row_id as Parents
,a.parent_account_id As ParentId
FROM siebelextract..account a
JOIN GetParentOfChild gp on a.row_id = gp.ParentId
)
SELECT TOP 1 @ChildId = Parents
FROM GetParentOfChild
ORDER BY Rn DESC
Run Code Online (Sandbox Code Playgroud)
它的作用是,给定任何一个孩子,它将返回根级父... ....程序完全正常工作...
出于好奇/实验的缘故,我将JOIN更改为Left Outer Join并报告
消息462,级别16,状态1,过程GetParent,第9行在递归公用表表达式'GetParentOfChild'的递归部分中不允许外连接.
我的问题是为什么CTE的递归部分不能接受Left Outer Join?它是按设计的吗?
谢谢
我编写了一个非常简单的CTE表达式,它检索用户所属的所有组的列表.
规则是这样的,用户可以在多个组中,并且组可以嵌套,以便组可以是另一个组的成员,此外,组可以是另一个组的共同成员,因此组A是组的成员B组和B组也是A组的成员.
我的CTE是这样的,显然它会产生无限递归:
;WITH GetMembershipInfo(entityId) AS( -- entity can be a user or group
SELECT k.ID as entityId FROM entities k WHERE k.id = @userId
UNION ALL
SELECT k.id FROM entities k
JOIN Xrelationships kc on kc.entityId = k.entityId
JOIN GetMembershipInfo m on m.entityId = kc.ChildID
)
Run Code Online (Sandbox Code Playgroud)
我找不到一个简单的解决方案来回溯我已记录的那些组.
我在考虑在CTE中使用额外的varchar参数来记录我访问过的所有组的列表,但是使用varchar太粗糙了,不是吗?
有没有更好的办法?
我是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) 我在数据库中有一个邻接列表,希望通过SQL SP将XML格式的数据传递给客户端.我正在尝试使用CTE和FOR XML,但我没有让XML节点嵌套.
仅供参考,这将代表一个站点地图.
表格结构:
CREATE TABLE [dbo].[PageHierarchy](
[ModuleId] [int] NOT NULL,
[PageId] [int] IDENTITY(1,1) NOT NULL,
[ParentPageId] [int] NULL,
[PageUrl] [nvarchar](100) NULL,
[PageTitle] [nvarchar](50) NOT NULL,
[PageOrder] [int] NULL)
Run Code Online (Sandbox Code Playgroud)
和CTE的开始:
;WITH cte AS
(
select * from PageHierarchy where ParentPageId is null
union all
select child.* from PageHierarchy child inner join cte parent on parent.PageId = child.ParentPageId
)
SELECT ModuleId, PageId, ParentPageId, PageUrl, PageTitle, PageOrder FROM cte
group by ModuleId, PageId, ParentPageId, PageUrl, PageTitle, PageOrder
order by PageOrder
for …Run Code Online (Sandbox Code Playgroud) 我用CTE写了一个'upsert'查询,看起来像这样:
WITH
new_data (id, value) AS (
VALUES (1, 2), (3, 4), ...
),
updated AS (
UPDATE table t set
value = t.value + new_data.value
FROM new_data
WHERE t.id = new_data.id
RETURNING t.*
)
INSERT INTO table (id, value)
SELECT id, value
FROM new_data
WHERE NOT EXISTS (
SELECT 1 FROM updated WHERE updated.id = new_data.id
)
Run Code Online (Sandbox Code Playgroud)
但是,我需要在我的应用程序中使用新值,但此查询不会返回任何内容.添加returning *到插入的末尾将返回已插入的所有行,但不会返回任何已更新的行.
那么,问题是(如何)我可以扩展它以返回已更新的行和插入的行?
编辑:当然我可以SELECT在一个事务中运行它然后运行,但我很想知道是否有单查询方式.
sql postgresql upsert common-table-expression postgresql-9.1
有没有人知道为什么当循环发生在顶级节点(根节点连接到根节点)时,Oracle继续遵循循环循环之外的路径?更重要的是,如何预防呢?
我有Oracle 11g第2版(11.2),我一直在探索分层查询.我将围绕Oracle数据库SQL语言参考第9-4页的图9-1中的树结构构建我的问题
我使用供应商和客户的概念为这棵树创建了一个表格结构:
create table t
( vendor varchar2(3)
, customer varchar2(3)
);
insert into t values ( '1' , '2' );
insert into t values ( '2' , '3' );
insert into t values ( '2' , '4' );
insert into t values ( '4' , '5' );
insert into t values ( '4' , '6' );
insert into t values ( '1' , '7' );
insert into t values ( '7' , '8' );
insert into t …Run Code Online (Sandbox Code Playgroud) 我之前发过类似的东西,但我现在从另一个方向接近这个,所以我开了一个新问题.我希望这没关系.
我一直在与CTE合作,根据父母费用创建一笔费用.SQL和详细信息可以在这里看到:
我不认为我在CTE上遗漏任何东西,但是当我使用一个大数据表(350万行)时,我遇到了问题.
该表tblChargeShare包含了我需要的其他一些信息,例如InvoiceID,因此我将CTE放在视图中vwChargeShareSubCharges并将其加入到表中.
查询:
Select t.* from vwChargeShareSubCharges t
inner join
tblChargeShare s
on t.CustomerID = s.CustomerID
and t.MasterChargeID = s.ChargeID
Where s.ChargeID = 1291094
Run Code Online (Sandbox Code Playgroud)
返回几毫秒的结果.
查询:
Select ChargeID from tblChargeShare Where InvoiceID = 1045854
Run Code Online (Sandbox Code Playgroud)
返回1行:
1291094
Run Code Online (Sandbox Code Playgroud)
但查询:
Select t.* from vwChargeShareSubCharges t
inner join
tblChargeShare s
on t.CustomerID = s.CustomerID
and t.MasterChargeID = s.ChargeID
Where InvoiceID = 1045854
Run Code Online (Sandbox Code Playgroud)
需要2-3分钟才能运行.
我保存了执行计划并将它们加载到SQL Sentry中.快速查询的树看起来像这样:

慢查询的计划是:

我尝试重新索引,通过调优顾问程序和子查询的各种组合运行查询.每当连接包含除PK之外的任何内容时,查询都很慢.
我在这里有一个类似的问题:
其中使用函数来执行子行的汇总而不是CTE.这是使用CTE重写以避免我现在遇到的同样问题.我已经阅读了该答案中的回复,但我并不是更明智 - 我阅读了一些有关提示和参数的信息,但我无法使其发挥作用.我以为使用CTE重写可以解决我的问题.在具有几千行的tblCharge上运行时查询很快.
在SQL 2008 …
我正在尝试在Oracle中创建一个CTE,它不会从现有表中进行选择,而是将数据插入其中.目前,我正在创建一个表,然后在查询完成后删除它.有没有办法创建一个有效地做同样事情的CTE?这是我目前的代码:
create table RTG_YEARS
(YR date);
insert into RTG_YEARS values (to_date('2013-01-01', 'yyyy-mm-dd'));
insert into RTG_YEARS values (to_date('2013-12-31', 'yyyy-mm-dd'));
insert into RTG_YEARS values (to_date('2014-01-01', 'yyyy-mm-dd'));
insert into RTG_YEARS values (to_date('2014-12-31', 'yyyy-mm-dd'));
insert into RTG_YEARS values (to_date('2015-01-01', 'yyyy-mm-dd'));
insert into RTG_YEARS values (to_date('2015-12-31', 'yyyy-mm-dd'));
Run Code Online (Sandbox Code Playgroud) sql ×5
postgresql ×2
t-sql ×2
cycle ×1
for-xml ×1
graph-theory ×1
hierarchy ×1
insert ×1
oracle ×1
oracle11g ×1
performance ×1
plsql ×1
recursion ×1
sql-server ×1
temp-tables ×1
upsert ×1
xml ×1