SQL平均常见结果,然后只列出其中的前2位

时间:2017-10-03 10:04:30

标签: sql oracle

CREATE TABLE CONFERENCESESSION(
SESSIONID CHAR(4),
BUILDINGNO CHAR(2),
ROOMNO CHAR(2),
SPEAKERID CHAR(2),
SESSIONDATE DATE,
SESSIONPRICE NUMBER(4, 2));

INSERT INTO CONFERENCESESSION VALUES('SS01','B1','R1','S1','3-MAY-17','12.50');
INSERT INTO CONFERENCESESSION VALUES('SS02','B2','R1','S2','4-JUNE-17','19.45');
INSERT INTO CONFERENCESESSION VALUES('SS03','B1','R2','S2','13-MAY-17','12.67');
INSERT INTO CONFERENCESESSION VALUES('SS04','B4','R2','S4','13-JUNE-17','14.56');
INSERT INTO CONFERENCESESSION VALUES('SS05','B3','R2','S5','23-MAY-17','14.56');
INSERT INTO CONFERENCESESSION VALUES('SS06','B3','R1','S5','3-JUNE-17','16.32');
INSERT INTO CONFERENCESESSION VALUES('SS07','B4','R2','S3','13-MAY-17','21.78');
INSERT INTO CONFERENCESESSION VALUES('SS08','B1','R2','S2','6-JUNE-17','16.82');
INSERT INTO CONFERENCESESSION VALUES('SS09','B2','R3','S4','13-MAY-17','17.90');
INSERT INTO CONFERENCESESSION VALUES('SS10','B4','R1','S3','6-JUNE-17','16.37');

SELECT BUILDINGNO, AVG(SESSIONPRICE)
FROM  CONFERENCESESSION 
GROUP BY BUILDINGNO
ORDER BY AVG(SESSIONPRICE) DESC;

我必须按照“建筑物编号”对conferencesession表进行分组,然后对这些结果进行平均。然后只在列表上打印2个最昂贵的结果

我以为我必须在某处使用“where rownum< = 2”,但无论我把它放在哪里,我的代码都会停止工作或显示错误的值

请帮忙吗? 谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用ROW_NUMBER()

SELECT s.BUILDINGNO,s.avg_prc
FROM(
    SELECT t.*,
           ROW_NUMBER() OVER(ORDER BY t.avg_prc DESC) as rnk
    FROM(
         SELECT BUILDINGNO, AVG(SESSIONPRICE) as avg_prc
         FROM  CONFERENCESESSION  
         GROUP BY BUILDINGNO) t ) s
WHERE s.rnk <= 2

然后你可以选择你喜欢的那个。他们排名从最大到最小1 ... N

答案 1 :(得分:0)

在子查询中执行GROUPORDER,然后限制外部查询中的行:

SELECT *
FROM   (
  SELECT BUILDINGNO,
         AVG(SESSIONPRICE) as avg_prc
  FROM   CONFERENCESESSION  
  GROUP BY BUILDINGNO
  ORDER BY avg_prc DESC
)
WHERE  ROWNUM <= 2;

另请注意:'3-MAY-17'不是日期 - 它是字符串文字,Oracle将尝试使用当前用户的TO_DATE( value, format_model, nlsparams )会话参数作为格式,使用NLS_DATE_FORMAT执行隐式转换model(以及第三个参数的其他NLS设置)。

您需要知道这些是在用户会话中设置的,并且可以由每个用户修改,因此如果用户更改这些参数,您的查询可以在不更改查询文本的情况下中断。

最好习惯使用日期文字DATE '2017-05-03'或使用所有参数TO_DATE( '3-MAY-17', 'DD-MON-RR', 'NLS_DATE_LANGUAGE=''ENGLISH''' )显式执行转换,而不是依赖隐式转换。