如何引用1:N关系链中的多个列

时间:2011-04-19 13:49:07

标签: sql aggregate one-to-many

我仍然在学习曲线中使用grails,我遇到了以下问题:

class Departement {
String  name    // "hr", "it"...

static hasMany = [bureaus:Office]
}


class Office {
String  bureaunumber    // 102, 104, 106...

static hasMany = [ppl:Personnel]
}


class Personnel {
String  name    // "Smith", "Walker"...
String  title   // "project manager", "ceo", "financial manager"...
Integer salary
}

目标是找到特定部门所有经理的薪水总和。结果必须提供工资总额,经理总数和部门名称,如下所示:

|dept    |total manager|wages   |
|--------|-------------|--------|
| hr     | 4           | 340000 |
| it     | 7           | 610400 |
| ...    | ...         | ...    |
| all    | 11          | 950400 |

我想用hibernate标准api创建一个结果集但是我坚持使用SQL查询来提供上面的结果。目前,它给了我适当的工资总额:

select sum(salary) wages
from personnel
where title LIKE '%manager%'
  and office_id in
  (
    select office.id
    from office
    where office.dept_id in
    (
      select dept.id
      from dept
      where name = 'hr'
    )
  )
很好 - 不幸的是,这一切都很好。有没有人知道如何计算每个部门的经理总数以及如何将部门名称添加到结果集?

非常感谢任何输入!

=========================

你好,伙计们, 谢谢你抽出时间回答我的问题!

我对Ben的建议解决方案的计数(经理)部分感到有点困惑,我在人事领域课程中没有管理员领域......我在那里想念一些东西吗?

尝试使用count(*)和count(personnel.name),但是它给了我所有员工的每个部门的工资总额,它也增加了总人数 - 而不仅仅是那些“经理”头衔: - /

所以运行查询后的结果如下所示:

|dept    |total manager|wages    |
|--------|-------------|---------|
| hr     | 139         | 3988800 |
| it     | 139         | 3988800 |
| ...    | 139         | 3988800 |
| all    | 139         | 3988800 |

========更新2:sql server 2005+语法到oracle ===========

SELECT
   CASE GROUPING(d.name)
     WHEN 1 THEN 'All:'
     ELSE d.name
   END dept,
   COUNT(*) total_manager,
   SUM(p.salary) wages
FROM departement d
   INNER JOIN office o ON d.id = o.dept_id
   INNER JOIN personnel p ON o.id = p.office_id
WHERE p.name LIKE '%manager%'
GROUP BY ROLLUP(d.name)

2 个答案:

答案 0 :(得分:0)

我认为你很亲密。使用SUM和COUNT时,有时需要在SQL中使用GROUP BY子句,所以也许这就是你所缺少的。类似的东西:

SELECT  dept,
        COUNT(managers),
        sum(salary) wages
FROM personal
WHERE title LIKE '%manager%'
AND office_id IN 
    (select office.id from office where office.dept_id in (select dept.id from dept where name = 'hr'))
GROUP BY managers

答案 1 :(得分:0)

在SQL Server 2005 +

SELECT
  CASE GROUPING(d.name)
    WHEN 1 THEN 'All:'
    ELSE d.name
  END AS dept,
  COUNT(*) AS total_manager,
  SUM(p.salary) AS wages
FROM dept d
  INNER JOIN office o ON d.id = o.dept_id
  INNER JOIN personnel p ON o.id = p.office_id
GROUP BY d.name WITH ROLLUP