2010-12-31 2 views
2

Я strugling с тем, что кажется простой проблемой для решения (по крайней мере для меня в MySQL/SqlServer!)Oracle Группа по выпускам

Я упростить проблему. Скажем, у меня есть следующая таблица:

Таблица ГОЛОСОВАТЬ

ID ID_IDEA DATE_VOTE with ID_IDEA FK(IDEA.ID) 
1 3  10/10/10 
2 0  09/09/10 
3 3  08/08/10 
4 3  11/11/10 
5 0  06/06/10 
6 1  05/05/10 

Я пытаюсь найти последние голоса, отданные для каждой отдельной идеи, то есть я хочу вернуть только строки с ID 4, 2 и 6 .

Кажется, что Oracle не может использовать GROUP BY без использования функции, такой как SUM(), AVG и т. Д. Я немного смущен тем, как это должно работать.

Просьба сообщить,

Спасибо.

ответ

7
SELECT id, 
     id_idea, 
     date_vote 
FROM (SELECT id, 
       id_idea, 
       date_vote, 
       Row_number() over (PARTITION BY id_idea 
             ORDER BY date_vote DESC NULLS LAST) AS rn 
     FROM VOTE) AS t 
WHERE rn = 1 
+1

Обычно, когда ORDERing DESC - это хорошая идея, чтобы заставить NULL быть LAST, поэтому вы с большей вероятностью возьмете строку с реальными данными. – EvilTeach

+0

@EvilTeach Мое предположение было бы в том, что это вряд ли будет иметь значение NULL, но будет сделана точка и сделана редактирование. –

+0

Это сработало чудесно. Большое спасибо – karlipoppins

1

Насколько я понимаю, вы ищете это:

 
SELECT id_idea, max(date_vote) 
FROM vote 
GROUP BY id_idea 

Edit: на второй мысли, если вам нужно, чтобы получить полную строку:

 
SELECT v.* 
FROM vote v 
    JOIN (SELECT id_idea, max(date_vote) as max_date 
     FROM vote 
     GROUP BY id_idea) t 
    ON t.id_idea = v.id_idea AND t.max_date = v.date_vote 
+0

Они хотят 'id', как я думаю. Наибольший n для группового запроса. –

+0

Вы комментируете Crossed my edit;) –

+0

Я все еще получаю ORA-00979: не ошибка выражения GROUP BY ... – karlipoppins

0

Я обычно делайте это с помощью first or last function. У этого есть немного странная конструкция, которая могла бы объяснить, почему она не используется очень часто. Следует отметить, что до тех пор, пока заказ пунктом является детерминированным, то макс/мин in't важно (но нужно, потому что это путь функция построена.

select 
    max(id) keep (dense_rank last order by date_vote) as id, 
    id_idea, 
    max(date_vote) 
    from vote 
group by id_idea 
1

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

SQL> create table vote(id,id_idea,date_vote) 
    2 as 
    3 select 1, 3, date '2010-10-10' from dual union all 
    4 select 2, 0, date '2010-09-09' from dual union all 
    5 select 3, 3, date '2010-08-08' from dual union all 
    6 select 4, 3, date '2010-11-11' from dual union all 
    7 select 5, 0, date '2010-06-06' from dual union all 
    8 select 6, 1, date '2010-05-05' from dual 
    9/

Table created. 

SQL> select max(id) keep (dense_rank last order by date_vote) id 
    2  , id_idea 
    3  , max(date_vote) date_vote 
    4 from vote 
    5 group by id_idea 
    6/

     ID ID_IDEA DATE_VOTE 
---------- ---------- ------------------- 
     2   0 09-09-2010 00:00:00 
     6   1 05-05-2010 00:00:00 
     4   3 11-11-2010 00:00:00 

3 rows selected. 

по сравнению с аналитическим варианта:

1) он работает (ок аналитическая один работает, если вы удалите «AS» в «AS т ')

2) он короче

3) это яснее (ок, это субъективно)

4) это чуть-чуть более производительным, см:

Это план для запроса агрегации :

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 2103353780 

--------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  3 | 39 |  4 (25)| 00:00:01 | 
| 1 | SORT GROUP BY  |  |  3 | 39 |  4 (25)| 00:00:01 | 
| 2 | TABLE ACCESS FULL| VOTE |  6 | 78 |  3 (0)| 00:00:01 | 
--------------------------------------------------------------------------- 

И это план для аналитического запроса:

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 781916126 

--------------------------------------------------------------------------------- 
| Id | Operation    | Name | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |  |  6 | 288 |  4 (25)| 00:00:01 | 
|* 1 | VIEW     |  |  6 | 288 |  4 (25)| 00:00:01 | 
|* 2 | WINDOW SORT PUSHED RANK|  |  6 | 78 |  4 (25)| 00:00:01 | 
| 3 | TABLE ACCESS FULL  | VOTE |  6 | 78 |  3 (0)| 00:00:01 | 
--------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    1 - filter("RN"=1) 
    2 - filter(ROW_NUMBER() OVER (PARTITION BY "ID_IDEA" ORDER BY 
       INTERNAL_FUNCTION("DATE_VOTE") DESC NULLS LAST)<=1) 

С уважением, Роб.

+0

Спасибо за ваш глубокий ответ Роб. На самом деле мы закончили тем, что делали что-то совершенно подобное, прежде чем читать ваш ответ. – karlipoppins