2016-02-11 2 views
0

Предположим, что у меня есть таблица, как показано ниже:запрашивая идентификатора, который имеет наибольшее количество просмотров

+----+-----------+ 
| ID | TIME | 
+----+-----------+ 
| 1 | 12-MAR-15 | 
| 2 | 23-APR-14 | 
| 2 | 01-DEC-14 | 
| 1 | 01-DEC-15 | 
| 3 | 05-NOV-15 | 
+----+-----------+ 

То, что я хочу сделать, это каждый год (год определяется как DATE), список ID, который имеет самый высокий счет в этом году. Так, например, ID 1 происходит больше всего в 2015 году, ID 2 происходит больше всего в 2014 году, и т.д.

Что у меня есть для запроса:

SELECT EXTRACT(year from time) "YEAR", COUNT(ID) "ID" 
FROM table 
GROUP BY EXTRACT(year from time) 
ORDER BY COUNT(ID) DESC; 

Но этот запрос просто подсчитывает, сколько раз год, как я могу исправить его до максимального количества идентификаторов в этом году?

Выход:

+------+----+ 
| YEAR | ID | 
+------+----+ 
| 2015 | 2 | 
| 2012 | 2 | 
+------+----+ 

Ожидаемый результат:

+------+----+ 
| YEAR | ID | 
+------+----+ 
| 2015 | 1 | 
| 2014 | 2 | 
+------+----+ 
+0

Пожалуйста, вы можете поставить результаты вы получаете и ожидаемые результаты. Спасибо –

+0

@ KamranFarzami, отредактированный выше, чтобы отразить это – user3268401

ответ

2

Начиная с вашего запроса выборки, первое изменение просто группы по идентификатору, а также с каждым годом.

SELECT EXTRACT(year from time) "YEAR" , id, COUNT(*) "TOTAL" 
FROM table 
GROUP BY EXTRACT(year from time), id 
ORDER BY EXTRACT(year from time) DESC, COUNT(*) DESC 

С, что вы могли бы найти строки, которые вы хотите путем визуального осмотра (первая строка за каждый год это идентификатор с наибольшим количеством строк).

Чтобы получить запрос, просто верните строки с наивысшими итогами, есть несколько способов сделать это. Вам нужно подумать о том, что вы хотите сделать, если есть связи - хотите ли вы видеть, что все идентификаторы привязаны к самому высокому за год или просто к произвольному?

Вот один подход - если есть связь, это должно возвращать только самый низкий из привязанных идентификаторов:

WITH groups AS (
    SELECT EXTRACT(year from time) "YEAR" , id, COUNT(*) "TOTAL" 
    FROM table 
    GROUP BY EXTRACT(year from time), id 
) 
SELECT year, MIN(id) KEEP (DENSE_RANK FIRST ORDER BY total DESC) 
FROM groups 
GROUP BY year 
ORDER BY year DESC 
2

Вы должны рассчитывать на идентификатор, а затем применить RANK на этот счет:

SELECT * 
FROM 
(
    SELECT EXTRACT(year from time) "YEAR" , ID, COUNT(*) AS cnt 
     , RANK() OVER (PARTITION BY "YEAR" ORDER BY COUNT(*) DESC) AS rnk 
    FROM table 
    GROUP BY EXTRACT(year from time), ID 
) dt 
WHERE rnk = 1 

Если это возвращает несколько строк с одинаковым высоким подсчетом в год, и вы хотите, чтобы один из них был случайным, вы можете переключиться на ROW_NUMBER.

0

Это должно делать то, что вы после этого, я думаю:

with sample_data as (select 1 id, to_date('12/03/2015', 'dd/mm/yyyy') time from dual union all 
        select 2 id, to_date('23/04/2014', 'dd/mm/yyyy') time from dual union all 
        select 2 id, to_date('01/12/2014', 'dd/mm/yyyy') time from dual union all 
        select 1 id, to_date('01/12/2015', 'dd/mm/yyyy') time from dual union all 
        select 3 id, to_date('05/11/2015', 'dd/mm/yyyy') time from dual) 
-- End of creating a subquery to mimick a table called "sample_data" containing your input data. 
-- See SQL below: 
select yr, 
     id most_frequent_id, 
     cnt_id_yr cnt_of_most_freq_id 
from (select to_char(time, 'yyyy') yr, 
       id, 
       count(*) cnt_id_yr, 
       dense_rank() over (partition by to_char(time, 'yyyy') order by count(*) desc) dr 
     from  sample_data 
     group by to_char(time, 'yyyy'), 
       id) 
where dr = 1; 

YR MOST_FREQUENT_ID CNT_OF_MOST_FREQ_ID 
---- ---------------- ------------------- 
2014    2     2 
2015    1     2 
Смежные вопросы