【发布时间】:2012-11-02 21:08:35
【问题描述】:
我再次与GROUP BY 作斗争。我可以处理的基础知识,但就是这样:如何在不破坏我的分组的情况下访问我在group by 中命名的不同列?请注意group by 只是我自己的想法,可能还有其他更好的方法。不过,它必须在 Oracle 中工作。
这是我的例子:
create table xxgroups (
groupid int not null primary key,
groupname varchar2(10)
);
insert into xxgroups values(100, 'Group 100');
insert into xxgroups values(200, 'Group 200');
drop table xxdata;
create table xxdata (
num1 int,
num2 int,
state_a int,
state_b int,
groupid int,
foreign key (groupid) references xxgroups(groupid)
);
-- "ranks" are 90, 40, null, 70:
insert into xxdata values(10, 10, 1, 4, 100);
insert into xxdata values(10, 10, 0, 4, 200);
insert into xxdata values(11, 11, 0, 3, 100);
insert into xxdata values(20, 22, 5, 7, 200);
任务是为每个distinct (num1, num2) 创建一个结果行,并打印groupname 与state_a 和state_b 中计算出的最高“排名”。
请注意,前两行具有相同的
nums,因此只应选择较高的排名——groupname为“Group 200”。
我认为基本的group by 已经很远了。
SELECT xd.num1||xd.num2 nummer, max(ranking.goodness)
FROM xxdata xd
, xxgroups xg
,( select state_a, state_b, r as goodness
from dual
model return updated rows
dimension by (0 state_a, 0 state_b) measures (0 r)
rules (r[1,4]=90, r[3,7]=80,r[5,7]=70, r[4,7]=60, r[0,7]=50, r[0,4]=40)
order by goodness desc
) ranking
WHERE xd.groupid=xg.groupid
and ranking.state_a (+) = xd.state_a
and ranking.state_b (+) = xd.state_b
GROUP BY xd.num1||xd.num2
ORDER BY nummer
;
结果是我需要的 90%:
nummer ranking
----------------
1010 90
1111
2022 70
100% 完美
nummer groupname
-------------------
1010 Group 100
1111 Group 100
2022 Group 200
- 棘手的部分是,我想要结果中的
groupname。而且我不能将它包含在select中,因为那样我必须 也将它放入group by中——我确实不想要(然后我不会从所有组中选择排名最高的条目) - 在我的解决方案中,使用
model表来计算“排名”。我确定还有其他解决方案。关键是,这是一个重要的计算,我不想做两次。 - 我从其他示例中知道,可以使用第二个查询返回原始行以获取
groupname,但我看不出我怎么能在这里做到这一点, 无需重复我的排名计算。 - 一个不错的建议是将
group by替换为LIMIT 1/ORDER BY goodness,并将此计算选择用作过滤子选择。但是a)Oracle 中没有LIMIT,我怀疑rownum<=1会在子选择中执行,并且b)无论如何我都无法绕开它。也许有办法?
【问题讨论】: