Tob*_*bia 7 t-sql sql-server common-table-expression
是否有解决方法在循环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
JOIN items i ON father.id=i.father
)
SELECT id, SUM(dailyconsumption)
FROM cte
GROUP BY id
Run Code Online (Sandbox Code Playgroud)
http://sqlfiddle.com/#!3/f4f2a/95
使用此有效查询,我将为所有项目(最终用户和子项目)填充所有dailyconsumption.请注意,父子关系可以超过1级.
现在我需要计算截止值(我的股票需要多少天).对于最终用途,它非常容易并且已经在第一次CTE中计算:库存/每日消耗.对于子项,它有点复杂: subitem.stock/subitem.dailyconsumption + MIN(father.cutoff) 其中MIN(father.cutoff)是本子项的所有父亲的最小截止.这是因为我需要另一个小组.
我是否需要另一个CTE来循环同一个父子关系?
感谢您的关注,对不起我的英语.
;WITH cte AS
(
SELECT id, father,
dailyconsumption,
(stock / dailyconsumption) AS cutoff,
0 AS [Level]
FROM items
WHERE father IS NULL
UNION ALL
SELECT i.id, i.father,
c.dailyconsumption * i.num,
i.stock / (c.dailyconsumption * i.num),
[Level] + 1
FROM cte c JOIN items i ON c.id = i.father
)
SELECT c.id, c.dailyconsumption, c.cutoff AS subItemsCutoff,
MIN(ct.cutoff) OVER(PARTITION BY ct.[Level]) AS fatherCutoff,
(c.cutoff + ISNULL(MIN(ct.cutoff) OVER(PARTITION BY ct.[Level]), 0)) AS Cutoff
FROM cte c LEFT JOIN cte ct ON c.father = ct.id
Run Code Online (Sandbox Code Playgroud)
关于SQLFiddle的演示
我建议改用变量表。声明该表,然后将这些记录插入其中。您需要找出一种在第二次插入命令时循环遍历它的方法。我有这个可以帮助你开始:
DECLARE @staging TABLE
(
id INT
,dailyconsumption FLOAT
,cutoff FLOAT
)
INSERT INTO @staging
SELECT
id,
dailyconsumption,
stock/dailyconsumption as cutoff
FROM
items
WHERE
father IS NULL
INSERT INTO @staging
SELECT
i.id,
SUM(father.dailyconsumption*i.num),
MAX(stock)/SUM(father.dailyconsumption*i.num)
FROM
@staging father
JOIN items i
ON father.id=i.father
group by
i.id
SELECT
id
,MIN(cutoff)
FROM
@staging
GROUP BY
id
Run Code Online (Sandbox Code Playgroud)