标签: cte

CTE 和临时表有什么区别?

通用表表达式 (CTE) 和临时表有什么区别?我什么时候应该使用一个?

CTE

WITH cte (Column1, Column2, Column3)
AS
(
    SELECT Column1, Column2, Column3
    FROM SomeTable
)

SELECT * FROM cte
Run Code Online (Sandbox Code Playgroud)

临时表

SELECT Column1, Column2, Column3
INTO #tmpTable
FROM SomeTable

SELECT * FROM #tmpTable
Run Code Online (Sandbox Code Playgroud)

sql-server cte

183
推荐指数
7
解决办法
19万
查看次数

32
推荐指数
2
解决办法
3567
查看次数

公共表表达式 (CTE) 的好处?

msdn

与派生表不同,CTE 可以是自引用的,并且可以在同一个查询中多次引用。

我经常使用 CTE,但我从未深入思考使用它们的好处。

如果我在同一个查询中多次引用 CTE:

  • 是否有任何性能优势?
  • 如果我进行自联接,SQL Server 会扫描目标表两次吗?

sql-server cte

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

SQL 递归实际上是如何工作的?

从其他编程语言转向 SQL,递归查询的结构看起来很奇怪。一步步走过来,仿佛分崩离析。

考虑以下简单示例:

CREATE TABLE #NUMS
(N BIGINT);

INSERT INTO #NUMS
VALUES (3), (5), (7);

WITH R AS
(
    SELECT N FROM #NUMS
    UNION ALL
    SELECT N*N AS N FROM R WHERE N*N < 10000000
)
SELECT N FROM R ORDER BY N;
Run Code Online (Sandbox Code Playgroud)

让我们来看看吧。

首先,执行锚成员并将结果集放入 R。因此 R 被初始化为 {3, 5, 7}。

然后,执行低于 UNION ALL 并且第一次执行递归成员。它在 R 上执行(即,在我们目前手头的 R 上:{3, 5, 7})。这导致 {9, 25, 49}。

这个新结果有什么用?它是否将 {9, 25, 49} 附加到现有的 {3, 5, 7},标记结果联合 R,然后从那里继续递归?或者它是否将 R 重新定义为这个新结果 {9, 25, 49} 并在以后进行所有联合?

两种选择都没有意义。 …

sql-server cte recursive

20
推荐指数
3
解决办法
4227
查看次数

创建一个计划指南来缓存(懒惰假脱机)CTE 结果

我通常通过首先构造一个使用正确计划的查询,然后将其复制到类似的查询中来创建计划指南。但是,这有时很棘手,尤其是在查询不完全相同的情况下。从头开始创建计划指南的正确方法是什么?

SQLKiwi 已经提到在 SSIS 中制定计划,有没有一种方法或有用的工具来帮助为 SQL Server 制定一个好的计划?

有问题的具体实例是这个 CTE:SQLFiddle

with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;
Run Code Online (Sandbox Code Playgroud)

有没有任何方法来使结果拿出正好3个不同的guidS和没有更多?我希望将来能够通过包含多次引用的 CTE 类型查询的计划指南来更好地回答问题,以克服一些 SQL Server CTE 怪癖。

sql-server cte t-sql

19
推荐指数
1
解决办法
2882
查看次数

递归 CTE 以找到所有孩子的总数

这是一个装配树,我想使用递归T-SQL查询(大概CTE)和下面的预期结果进行搜索。我想知道给定任何零件的每个组件的总量。

这意味着如果我搜索“铆钉”,我想知道程序集中每个级别的总数,而不仅仅是直接子项计数。

Assembly (id:1)
    |
    |-Rivet
    |-Rivet
    |-SubAssembly (id:2)
    |   |
    |   |-Rivet
    |   |-Bolt
    |   |-Bolt
    |   |-SubSubAssembly (id:3)
    |      |
    |      |-Rivet
    |      |-Rivet
    |
    |-SubAssembly (id:4)
       |-Rivet
       |-Bolt

    DESIRED Results
    -------
    ID, Count
    1 , 6
    2 , 3
    3 , 2
    4 , 1
Run Code Online (Sandbox Code Playgroud)

目前,我可以获得直接父母,但想知道如何扩展我的 CTE 以允许我向上滚动此信息。

With DirectParents AS(
--initialization
Select InstanceID, ParentID
From Instances i 
Where i.Part = 'Rivet'

UNION ALL
--recursive execution
Select i.InstanceID, i.ParentID
From PartInstances i  INNER …
Run Code Online (Sandbox Code Playgroud)

sql-server cte t-sql recursive

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

为什么不能在同一语句中更新插入 CTE 中的行?

在 PostgreSQL 9.5 中,给定一个使用以下方法创建的简单表:

create table tbl (
    id serial primary key,
    val integer
);
Run Code Online (Sandbox Code Playgroud)

我运行 SQL 来插入一个值,然后在同一个语句中更新它:

WITH newval AS (
    INSERT INTO tbl(val) VALUES (1) RETURNING id
) UPDATE tbl SET val=2 FROM newval WHERE tbl.id=newval.id;
Run Code Online (Sandbox Code Playgroud)

结果是 UPDATE 被忽略:

testdb=> select * from tbl;
????????????
? id ? val ?
????????????
?  1 ?   1 ?
????????????
Run Code Online (Sandbox Code Playgroud)

为什么是这样?这个限制是 SQL 标准的一部分(即存在于其他数据库中),还是特定于 PostgreSQL 可能在未来修复的部分?在使用查询文件说,多次更新不支持,但没有提到INSERT和UPDATE。

postgresql cte

17
推荐指数
2
解决办法
6053
查看次数

使用 WITH 的多个操作

有没有办法使用WITH语句执行多个操作?

就像是

WITH T AS
(
  SELECT * FROM Tbl
)
BEGIN
  OPEN P_OUTCURSOR FOR
    SELECT * FROM T;

  SELECT COUNT(*) INTO P_OUTCOUNT FROM T;
END;
Run Code Online (Sandbox Code Playgroud)

我想选择一些数据和它的计数...

oracle cte select

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

为什么 CTE 应该以分号开头?

我只是在看StackOverflow上的一篇文章,其中 Aaron Bertrand 建议使用 CTE 而不是数字表,这是执行手头任务的一种优雅方式。我的问题是,为什么 CTE 的第一行以分号开头?

;WITH n AS (SELECT TOP (10000) n FROM 
  (SELECT n = ROW_NUMBER() OVER
    (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
  ) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!
Run Code Online (Sandbox Code Playgroud)

这是为了确保 WITH 语句不会被解析为以前的内容SELECT或其他内容吗?我在 SQL Server 2005 BOL 中没有看到关于在 WITH 之前使用分号的内容。

sql-server syntax cte t-sql

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

从 CTE 内部调用时未执行 PostgreSQL 函数

只是希望证实我的观察并得到有关为什么会发生这种情况的解释。

我有一个函数定义为:

CREATE OR REPLACE FUNCTION "public"."__post_users_id_coin" ("coins" integer, "userid" integer) RETURNS TABLE (id integer) AS '
UPDATE
users
SET
coin = coin + coins
WHERE
userid = users.id
RETURNING
users.id' LANGUAGE "sql" COST 100 ROWS 1000
VOLATILE
RETURNS NULL ON NULL INPUT
SECURITY INVOKER
Run Code Online (Sandbox Code Playgroud)

当我从 CTE 调用此函数时,它执行 SQL 命令但不触发该函数,例如:

WITH test AS
(SELECT * FROM __post_users_id_coin(10, 1))

SELECT
1 -- Select 1 but update not performed
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我从 CTE 调用该函数,然后选择 CTE 的结果(或在没有 CTE 的情况下直接调用该函数),它将执行 SQL 命令并触发该函数,例如: …

postgresql cte

16
推荐指数
2
解决办法
2418
查看次数