Oracle SQL分组集返回多行

时间:2015-12-06 22:23:02

标签: sql oracle oracle11g group-by

我正在开发一个Oracle sql脚本,与所有其他部门位置(location_id = 1700)相比,显示一个部门位置(location_id <> 1700)的平均值 - 它正在比较两个值,我期待只返回两行。我能够找到一个这样的查询:

select d.LOCATION_ID, round(avg(e.salary),2) AS "AVG SALARY", count(d.LOCATION_ID) from departments d
join employees e on e.DEPARTMENT_ID = d.DEPARTMENT_ID
where d.location_id = 1700
group by grouping sets(d.LOCATION_ID);

这样我就会返回一行:
enter image description here

我的第二个查询返回四行而不是一行(就像我想的那样):

select round(avg(e.salary),2) AS "AVG SALARY", count(d.LOCATION_ID) from departments d
join employees e on e.DEPARTMENT_ID = d.DEPARTMENT_ID
where d.location_id <> 1700
group by grouping sets(d.LOCATION_ID);

这会返回4行,但我希望它只返回1:
enter image description here

我的希望是找出两个查询,然后将它们组合在一起 - 显然我需要在将它们放在一起之前克服第二个查询的障碍。
有什么想法吗?

3 个答案:

答案 0 :(得分:2)

尝试完全删除组别。听起来你只想要其中location_id = 1700和location_id&lt;&gt;的平均值。 1700然后UNION两个结果。

select '1700' as "LOCATION", round(avg(e.salary),2) AS "AVG SALARY", count(d.LOCATION_ID) as "COUNT"
from departments d
join employees e on e.DEPARTMENT_ID = d.DEPARTMENT_ID
where d.location_id = 1700

union

select '<>1700' as "LOCATION", round(avg(e.salary),2) AS "AVG SALARY", count(d.LOCATION_ID) as "COUNT"
from departments d
join employees e on e.DEPARTMENT_ID = d.DEPARTMENT_ID
where d.location_id <> 1700

答案 1 :(得分:1)

select应包含在union all中,用于第二个查询。现在,您可以使用select d.location_id, round(avg(e.salary),2) AS "AVG SALARY", count(d.LOCATION_ID) from departments d join employees e on e.DEPARTMENT_ID = d.DEPARTMENT_ID where d.location_id <> 1700 group by d.location_id 来组合结果集。

select
avg(case when d.location_id = 1700 then e.salary else 0 end) 
AS "AVG SALARY for location 1700", 
avg(case when d.location_id <> 1700 then e.salary else 0 end) 
AS "AVG SALARY for locations other than 1700"
from departments d
join employees e on e.DEPARTMENT_ID = d.DEPARTMENT_ID

然而,这可以使用条件聚合作为

在一个查询中表达
{{1}}

答案 2 :(得分:1)

您可以考虑使用case代替locationid

select (case when d.lcoation_id = 1700 then 1700 else -1 end) as LocationId,
       round(avg(e.salary), 2) AS "AVG SALARY",
       count(d.LOCATION_ID)
from departments d join
     employees e
     on e.DEPARTMENT_ID = d.DEPARTMENT_ID
group by grouping sets((case when d.lcoation_id = 1700 then 1700 else -1 end));

我不确定您是否需要grouping sets。如果你只想要两行,那么这可能就是你想要的:

select (case when d.lcoation_id = 1700 then 1700 else -1 end) as LocationId,
       round(avg(e.salary), 2) AS "AVG SALARY",
       count(d.LOCATION_ID)
from departments d join
     employees e
     on e.DEPARTMENT_ID = d.DEPARTMENT_ID
group by (case when d.lcoation_id = 1700 then 1700 else -1 end);