我现在有以下查询:
SELECT DISTINCT c.Name as CategoryName, SUM(Amount) OVER(partition by c.Name order by c.Name) as Total
FROM Statements s
LEFT JOIN Categories c on c.Id = s.CategoryId
WHERE Date >= '2016-01-01'
ORDER BY c.Name
它到目前为止工作并获得每个类别的总量,但我需要的是以下内容。
类别可以包含子类别。我希望得到每一个根类别及其每一行的所有子类别的总和。
表示类别A有子项B和C.我想得到Statements
中具有A,B或C类别的所有条目的总和。
类别表包含以下列:Id, Name, ParentId
。
声明表由以下coluimns组成:Id, Date, Amount, CategoryId
表类别的示例数据:
Id, Name, ParentId
1, A, null,
2, B, 1
3, C, 2
4, D, null
表格声明的示例数据
Id, Date, Amount, CategoryId
1, 2016-01-01, 100, 1
2, 2016-01-01, 200, 2
3, 2016-01-01, 800, 4
4, 2016-01-01, 300, 3
查询的输出应如下所示:
CategoryName, Total
A, 600
D, 800
理想情况下,我可以将parentCategoryId传递给我的样本null
中的where子句,但也可以是2。
任何提示赞赏:)
答案 0 :(得分:2)
一种常见的方法是使用递归CTE来构建层次结构。
;
WITH cte
AS (
SELECT [Id],
[Name],
[ParentId],
[Name] AS [Root]
FROM Categories
WHERE ParentId IS NULL
UNION ALL
SELECT c.[Id],
c.[Name],
c.[ParentId],
[Root]
FROM Categories c
JOIN cte ON c.ParentID = cte.Name
)
SELECT cte.[Root] AS [CategoryName],
SUM(Amount) AS [Total]
FROM cte
JOIN Statements s ON s.CategoryId = cte.Id
GROUP BY cte.[Root]
答案 1 :(得分:1)
这不是问题的答案(在我写这篇文章时,缺乏关于如何在数据中描述父/子关系的充分信息)。但是,查询对于OP的既定目的而言并不是正确的查询。正确的查询是一个简单的聚合:
SELECT c.Name as CategoryName, SUM(Amount) as Total
FROM Table s LEFT JOIN
Categories c
on c.Id = s.CategoryId
WHERE Date >= '2016-01-01'
GROUP BY c.Name
ORDER BY c.Name;
如果问题中的查询实际产生了有用的结果,给定每个类别的重复行,我会感到非常惊讶。