sql查询中的两级分组

时间:2014-11-13 23:34:54

标签: sql oracle grouping cube rollup

我有三个将在查询中使用的表格:

部门:
DepartmentID - PK
DepartmentName的


收益:
EarningID - PK
PersonID
EarningValue


人:
PersonID - PK
DepartmentID的

命名

我需要创建一个返回4列的查询:
- 部门名称 - 人的姓氏 - 所有人的收入总和
- 部门所有收入的总和

我正在阅读有关ROLLUP,CUBE和GROUPING SETS子句的内容,但我不知道如何在这里使用它。 重要的是我不能使用OVER(PARTITION

3 个答案:

答案 0 :(得分:1)

我从事DB2工作,但我快速浏览了一本Oracle手册,在这方面看起来非常接近DB2。这个查询应该让你非常接近终点线,虽然它暴露了3个结果列,其中Sum_Earnings代表所有部门的部门总数,人员总数或总计,具体取决于总和记录类型(GROUPING函数用于确定您正在处理的总行数级别。通过微小的调整,您应该能够将其转换为暴露4个结果列(如果您确实需要它)(提示:分组功能)。

select   decode( grouping( D.DepartmentName ), 1, 'All Departments', D.DepartmentName ) 
            as Department
        ,decode( grouping( P.Surname ), 1, 'All Persons', P.Surname ) as Person_Surname
        ,sum( E.EarningValue ) as Sum_Earnings 

from     Departments D
join     People      P
    on   P.DepartmentID = D.DepartmentID
join     Earnings    E
    on   E.PersonID = P.PersonID

group by rollup( D.DepartmentName, P.Surname )
order by grouping( D.DepartmentName ), Department, grouping( P.Surname ), Person_Surname

因为CUBE,ROLLUP和GROUPING SETS可以用更小的代码量执行这些任务,所以它们真的是要走的路,因为编码错误的可能性较小(一旦你绕过它们),如果您正在生成这样的摘要报告,通过允许数据库执行所有求和工作,您可能会获得更好的性能(而不是将详细信息行读入通过搅拌细节行来计算总计的程序 - 啊)。

通常需要我几次尝试才能在这些类型的查询中获得行排序和总标签正确,因为我不经常这样做(近年来很少报告),所以希望我没有起来。

答案 1 :(得分:0)

我认为这样的事情可以解决问题。 (假设SQL Server)

基本上,你是单独总结它们,然后再将它们连接在一起。

SELECT 
    DepartmentName,
    PersonEarningValue,
    Surname,
    PersonEarningValue
FROM
    (SELECT
        Departments.DepartmentID,
        Departments.DepartmentName,
        SUM(Earnings.EarningValue) as DeparmentEarningValue
    FROM Departments
    JOIN People   ON Departments.DepartmentID = People.DepartmentID
    JOIN Earnings ON People.PersonID = Earnings.PersonID
    GROUP BY Departments.DepartmentID, Departments.DepartmentName) as DepartmentSums
LEFT JOIN
    (SELECT
        DepartmentID,
        Surname,
        SUM(EarningValue) as PersonEarningValue
    FROM People   ON Departments.DepartmentID = People.DepartmentID
    JOIN Earnings ON People.PersonID = Earnings.PersonID
    GROUP BY DepartmentID, Surname) as PeopleSums
ON DepartmentSums.DepartmentID = PeopleSums.DepartmentID

答案 2 :(得分:0)

我尝试使用已发布的解决方案以及许多我的想法。我有四个正确总和的列,但我有部门的ID和人的ID,部门名称和姓氏的内容。 我如何更改查询以替换这两列?

SELECT DepartmentID, PersonID, SUM(EarningValue), PersonSum FROM People
JOIN Earnings USING(PersonID)
JOIN
(
SELECT DepartmentID, SUM(EarningValue) AS DepartmentSum FROM People
JOIN Earnings USING(PersonID)
GROUP BY DepartmentID
) USING (DepartmentID)
GROUP BY DepartmentID, PersonID, DepartmentSum
ORDER BY DepartmentID