是否有解决方法在循环CTE中使用GROUP BY或有解决方法?
我需要对CTE表的结果集进行分组,并在具有相同CTE的另一个循环中使用它,但是我得到以下错误:
不允许使用GROUP BY,HAVING或聚合函数 递归公用表表达式'cte'的递归部分。
以下是查询:
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
SQL-Fiddle(带样本数据)
编辑......这是逻辑问题
我有一组最终用户项(father = NULL)和其他一些子项(由字段父和字段num填充)。 我得到了最终用户项目的日常消费(我用“WHERE父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
http://sqlfiddle.com/#!3/f4f2a/95
使用此有效查询,我将为所有项目(最终用户和子项目)填充所有dailyconsumption。请注意,父子关系可以超过1级。
现在我需要计算截止值(我的库存需要多少天)。 对于最终用途,它非常容易并且已经在第一次CTE中计算出来: stock / dailyconsumption 。 对于子项,它有点复杂: subitem.stock / subitem.dailyconsumption + MIN(father.cutoff) 其中MIN(father.cutoff)是本子项目所有父亲的最小截止点。 这是因为我需要另一个小组。
我是否需要另一个CTE来循环同一个父子关系?
感谢您的关注,对不起我的英语。
答案 0 :(得分:5)
;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
SQLFiddle上的演示
答案 1 :(得分:0)
我建议使用变量表。声明表,然后将这些记录插入其中。您需要找到一种方法在第二次插入命令时循环它。我得到了这个让你入门:
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