групповая выборка по нескольким полям

Dzib
Дата: 29.10.2015 23:12:01
Здравствуйте,

Нужен совет, кому интересно прошу ответить.

Есть независимая одна таблица. Например STUDENT у нее столбцы ID, NAME, NATIONALITY, DIRRECTION, DATE

Нужно отсортировать по дате начиная от старшей и вернуть первых 10 строк, с уникальной парой NATIONALITY и DIRRECTION.
Не важно какой один из множества студентов с одинаковыми NATIONALITY и DIRRECTION буду возвращены.


Спасибо за ответы.
mcureenab
Дата: 30.10.2015 00:02:50
контрольный пример приготовь хотя бы, чтобы было на чем запрос попробовать.
hardhouse
Дата: 30.10.2015 00:49:24
пример:
with t as (
    select 'name1' as name, 'nat1' as nationality, 'dir1' as dirrection, to_date('11.11.2000','dd.mm.yyyy') as dt from dual union all
    select 'name1' as name, 'nat1' as nationality, 'dir1' as dirrection, to_date('11.11.2000','dd.mm.yyyy') as dt from dual union all
    select 'name2' as name, 'nat2' as nationality, 'dir2' as dirrection, to_date('10.11.2000','dd.mm.yyyy') as dt from dual union all
    select 'name3' as name, 'nat3' as nationality, 'dir3' as dirrection, to_date('09.11.2000','dd.mm.yyyy') as dt from dual union all
    select 'name4' as name, 'nat4' as nationality, 'dir4' as dirrection, to_date('08.11.2000','dd.mm.yyyy') as dt from dual
)
select name, nationality, dirrection, min(dt) as o_dt from t
group by name, nationality, dirrection having count(*)=1
order by o_dt desc
fetch first 2 row only;


если последняя кляуза не подходит - используйте row_number()
Dzib
Дата: 30.10.2015 00:51:55
Спасибо большое, как то сложно очень.
Хорошо, но давайте изменим сортировку не по дате а по ID. От меньшей к большей. Дату уберем.

CREATE TABLE STUDENT (
         ID      INTEGER,
         NAME      VARCHAR2(255) NOT NULL,
         NATIONALITY    VARCHAR2(255) NOT NULL,
         DIRRECTION      VARCHAR2(255) NOT NULL
         )

INSERT INTO STUDENT VALUES (3, 'Andrew', 'US', 'Math');
INSERT INTO STUDENT VALUES (2, 'Ostin', 'US', 'Math');
INSERT INTO STUDENT VALUES (1, 'Andy', 'US', 'Math');
INSERT INTO STUDENT VALUES (5, 'Bob', 'UK', 'Math');
INSERT INTO STUDENT VALUES (4, 'Greg', 'PL', 'Math');


В конечном итоге должно вернуть такие строки:
1 Andy US Math
4 Greg PL Math
5 Bob UK Math
Alhymik
Дата: 30.10.2015 02:01:35
Dzib
Спасибо большое, как то сложно очень.
Хорошо, но давайте изменим сортировку не по дате а по ID. От меньшей к большей. Дату уберем.

CREATE TABLE STUDENT (
         ID      INTEGER,
         NAME      VARCHAR2(255) NOT NULL,
         NATIONALITY    VARCHAR2(255) NOT NULL,
         DIRRECTION      VARCHAR2(255) NOT NULL
         )

INSERT INTO STUDENT VALUES (3, 'Andrew', 'US', 'Math');
INSERT INTO STUDENT VALUES (2, 'Ostin', 'US', 'Math');
INSERT INTO STUDENT VALUES (1, 'Andy', 'US', 'Math');
INSERT INTO STUDENT VALUES (5, 'Bob', 'UK', 'Math');
INSERT INTO STUDENT VALUES (4, 'Greg', 'PL', 'Math');


В конечном итоге должно вернуть такие строки:
1 Andy US Math
4 Greg PL Math
5 Bob UK Math

подозреваю, что проще некуда - придется разбираться
select min(id) id,
       min(name) keep (dense_rank first order by id) name,
       nationality, 
       dirrection
from student
group by nationality, dirrection
order by 1

полная версия с датой, если под старшей датой подразумевалась та, что раньше и если id уникален
select  
  min(id) keep (dense_rank first order by dt) id,
  min(name) keep (dense_rank first order by dt, id) name,
  nationality, 
  dirrection,
  min(dt) dt
from student
group by nationality, dirrection
order by 5
fetch first 10 row only
Alhymik
Дата: 30.10.2015 03:14:18
или на крайняк да, row_number
select *
from (select s.*, 
             row_number() over (partition by nationality, dirrection order by dt) as rn
      from student s)
where rn = 1
order by dt
fetch first 10 row only 
Dzib
Дата: 30.10.2015 12:27:50
автор
select min(id) id,
min(name) keep (dense_rank first order by id) name,
nationality,
dirrection
from student
group by nationality, dirrection
order by 1


Эта кверя у меня сработала, но не совсем так как надо.
У меня 11g оракл.
Не знаю почему но когда добавляю fetch first 10 row only пишет:
автор
Error at Command Line : 8 Column : 1
Error report -
SQL Error: ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"


Так же и с другими кверями где fetch first 10 row only
Alhymik
Дата: 30.10.2015 12:48:13
Dzib
Так же и с другими кверями где fetch first 10 row only

Это фишка из 12-го оракла. Тогда роунум.
select * 
from (select min(id) id,
             min(name) keep (dense_rank first order by id) name,
             nationality, 
             dirrection
      from student
      group by nationality, dirrection
      order by 1
)
where rownum <= 2
Dzib
Дата: 30.10.2015 13:19:27
Спасибо большое,
к сожелению я не понимаю как работает ключевое слово keep даже почитав документацию.

Я от себя написал вот такую кверю:

SELECT * 
FROM  (SELECT * 
       FROM   STUDENT 
       WHERE  ID IN (SELECT ID 
                     FROM   (SELECT MIN(ID) id, 
                                    NATIONALITY, 
                                    DIRRECTION 
                             FROM   STUDENT
                             GROUP  BY NATIONALITY, 
                                       DIRRECTION)) 
       ORDER  BY 1) 
WHERE  ROWNUM <= 3 


На сколько она плохая?
bishnike
Дата: 30.10.2015 13:30:32
Dzib,

вспомнилась юморина про даму с кошелкой :)

"Женщина открыла сумочку, достала кошелочку, закрыла сумочку, открыла кошелочку, достала кошелек, закрыла кошелочку, открыла сумочку, положила туда кошелочку, закрыла сумочку, открыла кошелек положила туда билет, закрыла кошелек, открыла сумочку, достала кошелочку, закрыла сумочку, открыла кошелочку, положила туда кошелек, закрыла кошелочку, открыла сумочку, положила туда кошелочку, закрыла сумочку."