2014-11-19 2 views
0

Вот моя схема:SQL- Поиск пользователей с максимальным средним баллом

create TABLE sample (
    userId  INT, 
    score  INT 
); 

INSERT INTO sample VALUES (1,10); 
INSERT INTO sample VALUES (1,15); 
INSERT INTO sample VALUES (1,20); 

INSERT INTO sample VALUES (2,100); 
INSERT INTO sample VALUES (2,200); 
INSERT INTO sample VALUES (2,500); 

INSERT INTO sample VALUES (4,100); 
INSERT INTO sample VALUES (4,200); 
INSERT INTO sample VALUES (4,500); 

INSERT INTO sample VALUES (3,5); 
INSERT INTO sample VALUES (3,5); 
INSERT INTO sample VALUES (3,10); 
INSERT INTO sample VALUES (3,7); 
INSERT INTO sample VALUES (3,2); 

Я хочу, чтобы найти идентификатор пользователя и тех, кто имеет максимальную высокий средний балл. Обратите внимание, что может быть больше одного! Таким образом, для приведенных выше выборочных данных ответ будет: 2 и 4, потому что они оба имеют средний балл 266,666 ....

У меня есть рабочий SQL для этой проблемы:

select s.USERID 
from sample s 
group by USERID 
having AVG(s.SCORE) IN (
    -- Gets the Maximum Average Score (returns only 1 result) 
    select MAX(average_score) as Max_Average_Score 
    from (
    -- Gets the Average Score 
    select AVG(s2.SCORE) as average_score 
    from sample s2 
    group by USERID 
) 
); 

Но я думаю, что это немного неэффективно, потому что я расчет среднего балла в два раз. Один раз для основного SQL и снова для поиска максимума avg. Есть ли способ лучше?

Примечание: Я использую SQL Plus

+0

увидеть это: HTTP: // stackoverflow.com/questions/10557897/sql-getting-a-maxavgcolumn –

+0

Поддерживает ли каждый пользователь имеют такое же количество записей? Если да, то вы можете просто использовать СУММ, а не AVG, который может быстрее вычислить ... – mlinth

+0

Нет, это может быть иначе. Мое сообщение будет отредактировано. –

ответ

2

Я могу только сказать, как бы я решил это с помощью DB2 SQL. Я бы создал временную таблицу, в которой вы можете сохранить средний балл для каждого пользователя и выбрать максимальное значение из него. Это возможно и в sql plus: How to create a temporary table in Oracle.

Вот решение в DB2 Синтаксис (не тестировалось)

http://www.cs.newpaltz.edu/~pletcha/DB/db2_TempTables.html

WITH tempTable 
AS (select userid, AVG(score) FROM sample GROUP BY userid) 

SELECT * FROM tempTable WHERE score = (SELECT MAX(score) FROM tempTable) 
+1

Это не «временная таблица», это «общее табличное выражение» (но будет работать и для Oracle точно так же) –

+0

Я нашел эту ссылку полезной в отношении временных таблиц: http://www.dba-oracle.com/ t_sql_rewrite_temporary_tables.htm в Oracle –

4
select userid from 
(select userid, rank() over (order by avg(score) desc) rw 
from sample group by userid) 
where rw = 1; 

CALCulate Avg балл для каждого пользователя, чем вычислить ранг каждой забьет с помощью аналитических функций (которые выполняются после группировки). Наконец, получите строки с первым разрядом

0

Listo, изменено на Oracle:

select userId, AVG(score) AS promedio 
from [sample] 
where rownum = 1 
group by userId 
order by AVG(score) desc 
+1

Это не синтаксис Oracle. –

+1

и некоторые из них не на английском языке. –

+0

'[sample]' является недопустимым идентификатором SQL. –

Смежные вопросы