标签: common-table-expression

自连接中引用的SQL Server CTE速度很慢

我编写了一个表值UDF,它以CTE开头,从大表中返回行的子集.CTE中有几个连接.一对内部和一个左边连接到其他表,这些表不包含很多行.CTE有一个where子句,它返回日期范围内的行,以便只返回所需的行.

然后,我在4个自左连接中引用此CTE,以便使用不同的标准构建小计.

查询非常复杂,但这是一个简化的伪版本

WITH DataCTE as
(
     SELECT [columns] FROM table
                      INNER JOIN table2
                      ON [...]

                      INNER JOIN table3
                      ON [...]

                      LEFT JOIN table3
                      ON [...]
)
SELECT [aggregates_columns of each subset] FROM DataCTE Main
LEFT JOIN DataCTE BananasSubset
               ON [...] 
             AND Product = 'Bananas'
             AND Quality = 100
LEFT JOIN DataCTE DamagedBananasSubset
               ON [...]
             AND Product = 'Bananas'
             AND Quality < 20
LEFT JOIN DataCTE MangosSubset
               ON [...]
GROUP BY [
Run Code Online (Sandbox Code Playgroud)

我觉得SQL Server会感到困惑并为每次自我加入调用CTE,这似乎通过查看执行计划得到了证实,尽管我承认自己并不是那些阅读它们的专家.

我会假设SQL Server足够聪明,只能从CTE执行一次数据检索,而不是多次执行.

我尝试了相同的方法,但不是使用CTE来获取数据的子集,我使用了与CTE中相同的选择查询,而是将其输出到临时表.

引用CTE版本的版本需要40秒.引用临时表的版本需要1到2秒.

为什么SQL Server不够智能,无法将CTE结果保留在内存中? …

sql-server performance temp-tables common-table-expression

8
推荐指数
1
解决办法
6247
查看次数

在不使用CTE的情况下,是否存在逻辑等效且有效的查询版本?

我对postgresql 9.2系统有一个查询,它的正常形式大约需要20秒,但在使用CTE时只需要大约120ms.

为简洁起见,我简化了两个查询.

这是正常形式(大约需要20秒):

SELECT *
FROM tableA
WHERE (columna = 1 OR columnb = 2) AND
    atype = 35 AND
    aid IN (1, 2, 3)
ORDER BY modified_at DESC
LIMIT 25;
Run Code Online (Sandbox Code Playgroud)

以下是此查询的说明:http://explain.depesz.com/s/2v8

CTE表格(约120ms):

WITH raw AS (
    SELECT *
    FROM tableA
    WHERE (columna = 1 OR columnb = 2) AND
        atype = 35 AND
        aid IN (1, 2, 3)
)
SELECT *
FROM raw
ORDER BY modified_at DESC
LIMIT 25;
Run Code Online (Sandbox Code Playgroud)

以下是CTE的解释:http://explain.depesz.com/s/uxy

只需ORDER …

postgresql common-table-expression

8
推荐指数
1
解决办法
1729
查看次数

IsNumeric失败并显示"当前命令发生严重错误".SQL Server 2014 CTE

我正在运行一系列生成数据库的脚本.它们在SQL Server 2012(11.0.5058.0)上运行完成.在SQL Server 2014(12.0.4213.0)上,脚本错误:

消息0,级别11,状态0,行0
当前命令发生严重错误.结果(如果有的话)应该被丢弃.

消息0,级别20,状态0,行0
当前命令发生严重错误.结果(如果有的话)应该被丢弃.

看来,IsNumeric在CTE查询中使用语句的结果会破坏查询构建,因为不需要行来导致错误.我遇到的案例的简化版本是:

CREATE TABLE #Temp1 ( CTECol VARCHAR );
CREATE TABLE #Temp2 ( NumCol Int null);
;
WITH cte AS 
(
    SELECT 
        CASE WHEN ISNUMERIC(t.CTECol) = 1 
                THEN 1 
                ELSE null
        END as IsNCol1
    FROM
        #Temp1 t
)
SELECT * 
FROM #Temp2 
JOIN cte ON #Temp2.NumCol = cte.IsNCol1
Run Code Online (Sandbox Code Playgroud)

我能找到的最简单的案例是:

CREATE TABLE #Temp3 ( CTECol Int );
CREATE TABLE #Temp4 ( NumCol Int );
;
WITH cte AS 
(
    SELECT ISNUMERIC(t.CTECol) …
Run Code Online (Sandbox Code Playgroud)

sql-server isnumeric common-table-expression sql-server-2014

8
推荐指数
1
解决办法
424
查看次数

"With"关键字在SQL中如何工作?

这么多次见过with,很多次SQL Server都问;过它

;with ...工作怎么样?

;with coords(...) as (
SELECT * ...
)
Run Code Online (Sandbox Code Playgroud)

为什么必须;在它之前?

sql common-table-expression sql-server-2008

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

如何在深度优先搜索中正确标记树的分支

我有一个像这样结构的树:

     __2__3__4
    /   \__5__6
0__1___7/__8__9
   \\
    \\__10__11__12
     \__  __  __
        13  14  15
Run Code Online (Sandbox Code Playgroud)

节点1有四个子节点(2,7,10,13),节点2和节点7各有两个子节点(作为子节点共享节点5).我要做的是创建一个CTE,它提供包含父节点,节点,远离根的距离以及包含在其中的分支(或分支)的记录.

IF (OBJECT_ID('tempdb..#Discovered') IS NOT NULL)
BEGIN
    DROP TABLE #Discovered
END

CREATE TABLE #Discovered
(
    ID int PRIMARY KEY NOT NULL,
    Predecessor int NULL,
    OrderDiscovered int
);

INSERT INTO #Discovered (ID, Predecessor, OrderDiscovered)
VALUES (@nodeId, NULL, 0);

    --loop through node connections table in a breadth first manner
WHILE @@ROWCOUNT > 0
BEGIN
    INSERT INTO #Discovered (ID, Predecessor, OrderDiscovered)
    SELECT c.node2_id
               ,MIN(c.node1_id)
               ,MIN(d.OrderDiscovered) + 1

    FROM #Discovered d …
Run Code Online (Sandbox Code Playgroud)

t-sql common-table-expression sql-server-2008 depth-first-search

7
推荐指数
1
解决办法
855
查看次数

窗口函数和更多"本地"聚合

假设我有这个表:

select * from window_test;

 k | v
---+---
 a | 1
 a | 2
 b | 3
 a | 4
Run Code Online (Sandbox Code Playgroud)

最终我想得到:

 k | min_v | max_v
---+-------+-------
 a | 1     | 2
 b | 3     | 3
 a | 4     | 4
Run Code Online (Sandbox Code Playgroud)

但我会很高兴得到这个(因为我可以很容易地过滤它distinct):

 k | min_v | max_v
---+-------+-------
 a | 1     | 2
 a | 1     | 2
 b | 3     | 3
 a | 4     | 4
Run Code Online (Sandbox Code Playgroud)

使用PostgreSQL 9.1+窗口函数可以实现这一点吗?我试图了解我是否可以使用单独的分区来处理k=a此示例中的第一次和最后一次(按顺序排列v).

postgresql common-table-expression window-functions

7
推荐指数
1
解决办法
1402
查看次数

如何解析Oracle 10g中的相邻列表?

我有这样一张桌子:

+---------+--------+
| EMP_ID  | MGR_iD |
+---------+--------+
|       1 |      1 |
|       2 |      1 |
|       3 |      1 |
|       4 |      2 |
|       5 |      2 |
|       6 |      2 |
|       7 |      3 |
|       8 |      5 |
|       9 |      7 |
|      10 |      5 |
|      11 |      7 |
|      12 |      9 |
|      13 |      9 |
|      14 |      9 |
+---------+--------+
Run Code Online (Sandbox Code Playgroud)

我正在尝试解析此相邻列表以生成以下结果集: …

sql oracle hierarchy oracle10g common-table-expression

7
推荐指数
2
解决办法
237
查看次数

TSQL GROUP BY在递归CTE中

是否有解决方法在循环CTE中使用GROUP BY或有解决方法?

我需要对CTE表的结果集进行分组,并在具有相同CTE的另一个循环中使用它,但是我得到以下错误:

递归公用表表达式"cte"的递归部分中不允许使用GROUP BY,HAVING或聚合函数.

这是查询:

WITH cte
    AS
    (
        SELECT
          id,
          dailyconsumption,
          stock/dailyconsumption as cutoff
        FROM items
        WHERE father IS NULL


        UNION ALL

        SELECT
          i.id,
          SUM(father.dailyconsumption*i.num),
          MAX(stock)/SUM(father.dailyconsumption*i.num)
        FROM cte father
        JOIN items i ON father.id=i.father
        group by i.id
    )

SELECT id, MIN(cutoff)
FROM cte
GROUP BY id
Run Code Online (Sandbox Code Playgroud)

SQL-Fiddle(带有示例数据)


编辑......这是合乎逻辑的问题

我有一组最终用户项(父= NULL)和其他一些子项(由字段父和字段num填充).我只为最终用户项目获得了每日消费(我用"WHERE father IS NULL"开始我的cte),并且子项的dailyconsumption由SUM(father.dailyconsumption*item.num)计算.

WITH cte AS(
    SELECT
      id,
      dailyconsumption,
      stock/dailyconsumption as cutoff
    FROM items
    WHERE father IS NULL


    UNION ALL

    SELECT
      i.id,
      father.dailyconsumption*i.num
      0
    FROM cte father …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server common-table-expression

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

SQL: WITH clause with parameters?

In Oracle SQL Developer, I am using a WITH clause, in this (simplified) way:

WITH
foos AS
    SELECT *
    FROM my_table
    WHERE field = 'foo'
bars AS
    SELECT *
    FROM my_table
    WHERE field = 'bar'
SELECT *
FROM foo
INNER JOIN bar
ON foo.id = bar.id
Run Code Online (Sandbox Code Playgroud)

I would like to be able to factor out the 'foo' and 'bar' strings, so that I can have something like:

WITH
subq(my_arg) AS
    SELECT *
    FROM my_table
    WHERE field = my_arg
SELECT * …
Run Code Online (Sandbox Code Playgroud)

sql oracle arguments common-table-expression

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

postgresql在单个查询中更新多个表

我有2个表格如下:

  1. serial_table

    id CHARACTER VARYING(20),
    serial_key CHARACTER VARYING(20),
    PRIMARY KEY(id, serial_key)
    
    Run Code Online (Sandbox Code Playgroud)
  2. serial_rate:

    id CHARACTER VARYING(20), 
    serial_key CHARACTER VARYING(20),
    rate NUMERIC,
    PRIMARY KEY(id, serial_key),
    FOREIGN KEY (id, serial_key) REFERENCES serial_table(id, serial_key)
    
    Run Code Online (Sandbox Code Playgroud)

现在我想更新serial_rate.rateserial_table.serial_key从单个SQL查询更新,如:

UPDATE inventory.serial_table AS s 
JOIN inventory.serial_rate AS r 
ON (s.id, s.serial_key) = (r.id, r.serial_key) 
SET s.serial_key = '0002', r.rate = 22.53
WHERE (s.id, s.serial_key) = ('01', '002');
Run Code Online (Sandbox Code Playgroud)

我知道的是不正确的.是否有可能这样做,因为我想使用该语句PreparedStatement在Java中创建?

编辑 这个问题PreparedStatements与Java 无关这是关于我想在创建时作为参数传递的SQL语法PreparedStatement.我不想要任何答案PreparedStatement.

sql postgresql common-table-expression sql-update

7
推荐指数
2
解决办法
8251
查看次数