помогите составить SQL запросик(Oracle)
group by b,c
Сто лет уже не писал запросы, надеюсь не напутал.
select b, c from (
select b, c, row_number over (partition by b, c order by a desc) rn from table
) where rn = 1;
ЗЫ
Ксожалению, есть еще поля кроме a,b u c =(
Подобные мысли у меня тоже были, но суть в том, что сам запрос немаленький, много полей, сложные условия фильтрации, хотелось что нить совсем простое )
много полейпоставь в селектах звёздочки

первый ты сам назвал:
выборки максимально значения поля a в подзапросе и фильтрации по нему
SELECT t.a AS a,
t.b AS b,
t.c AS c,
t.e AS d,
t.d AS e
FROM tab t,
(SELECT MAX (a b, c FROM tab GROUP BY b, c) maxt
WHERE t.a = maxt.a AND
t.b = maxt.b AND
t.c = maxt.c AND
<нужные тебе условия>
ещё два используют аналитические функции (Update: выше уже привели их):
SELECT *
FROM (
SELECT t.a AS a,
t.b AS b,
t.c AS c,
t.d AS d,
t.e AS e,
ROW_NUMBER OVER (PARTITION BY t.b, t.c ORDER BY t.a DESC) AS rn
FROM tab t
WHERE <нужные тебе условия> )
WHERE rn = 1
SELECT MAX(t.a) AS a,
t.b AS b,
t.c AS c,
MAX (t.d) KEEP (DENSE_RANK LAST ORDER BY t.a) AS d,
MAX (t.e) KEEP (DENSE_RANK LAST ORDER BY t.a) AS e
<и так для всех полей, которые просто надо извлечь (т.е. без группировки по ним)>
FROM tab t
WHERE
<нужные тебе условия>
GROUP BY t.b, t.c
здесь d, e - просто некие поля, которые не используются для группировки, но их тоже требуется извлечь запросом.
наверняка для нее есть какие то простые методы (кроме выборки максимально значения поля a в подзапросе и фильтрации по нему)Есть, но используют аналитические функции. Что проще - фиг знает, по мне так проще без них

А вот про производительность разных вариантов ничего сказать не могу к сожалению

Знаю только, что два варианта с аналитическими функциями, приведённые мною выше - одинаковы. А вот как они в сравнении с выборкой максимального значения в подзапросе - не знаю.
Там zafhoz говорил, что в 1,5 раза быстрее у него получилось.
но я из той темы:
1) так и не понял, в 1.5 раза быстрее чем что?

2) не видел планов исполнения запросов
3) не видел индексов
1) что за ROW_NUMBER
2) Что за keep в третьем варианте
есть два вопроса :http://download-east.oracle.com/docs/cd/B19306_01/server.102...
1) что за ROW_NUMBER
2) Что за keep в третьем вариантеhttp://www.ss64.com/orasyntax/an_firstlast.html
никого ещё не смущает, что второй и третий варианты выдают разные результаты?

CREATE TABLE TAB
(
id NUMBER NOT NULL,
a DATE NOT NULL,
b CHAR(1) NOT NULL,
c CHAR(1) NOT NULL,
d VARCHAR2(16
e VARCHAR2(16)
);
ALTER TABLE TAB ADD (CONSTRAINT TAB_PK PRIMARY KEY (id;
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (1, TO_Date( '06/20/2007 02:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '1', '1', 'abc', 'def');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (2, TO_Date( '06/19/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '1', '1', 'qaz', 'wsx');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (3, TO_Date( '06/21/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '1', '1', 'rfd', 'rfv');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (4, TO_Date( '06/06/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '2', '1', 'ert', 'dfg');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (5, TO_Date( '06/02/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '2', '2', 'ert', 'ddf');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (6, TO_Date( '06/05/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '1', '2', 'rft', 'dfg');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (7, TO_Date( '06/03/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '2', '1', 'cvb', 'pl,');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (8, TO_Date( '06/15/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '2', '2', 'cvb', 'kjh');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (9, TO_Date( '06/25/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '1', '2', 'cvb', 'zxc');
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (10, TO_Date( '06/11/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '2', '1', 'plm', 'okm');
COMMIT;
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD';
Session altered.
SQL> SELECT *
2 FROM tab t
3 ORDER BY t.b, t.c, t.id;
ID A B C D E
---------- ---------- - - ---------------- ----------------
1 2007/06/20 1 1 abc def
2 2007/06/19 1 1 qaz wsx
3 2007/06/21 1 1 rfd rfv
6 2007/06/05 1 2 rft dfg
9 2007/06/25 1 2 cvb zxc
4 2007/06/06 2 1 ert dfg
7 2007/06/03 2 1 cvb pl,
10 2007/06/11 2 1 plm okm
5 2007/06/02 2 2 ert ddf
8 2007/06/15 2 2 cvb kjh
10 rows selected.
SQL> SELECT t.id AS id,
2 t.a AS a,
3 t.b AS b,
4 t.c AS c,
5 t.d AS d,
6 t.e AS e
7 FROM tab t,
8 (SELECT MAX(a) a, b, c FROM tab GROUP BY b, c) tmax
9 WHERE t.a = tmax.a AND
10 t.b = tmax.b AND
11 t.c = tmax.c
12 ORDER BY b,c;
ID A B C D E
---------- ---------- - - ---------------- ----------------
3 2007/06/21 1 1 rfd rfv
9 2007/06/25 1 2 cvb zxc
10 2007/06/11 2 1 plm okm
8 2007/06/15 2 2 cvb kjh
SQL> SELECT *
2 FROM (
3 SELECT t.id AS id,
4 t.a AS a,
5 t.b AS b,
6 t.c AS c,
7 t.d AS d,
8 t.e AS e,
9 ROW_NUMBER OVER (PARTITION BY t.b, t.c ORDER BY t.a DESC) AS rn
10 FROM tab t
11 )
12 WHERE rn = 1
13 ORDER BY b,c;
ID A B C D E RN
---------- ---------- - - ---------------- ---------------- ----------
3 2007/06/21 1 1 rfd rfv 1
9 2007/06/25 1 2 cvb zxc 1
10 2007/06/11 2 1 plm okm 1
8 2007/06/15 2 2 cvb kjh 1
SQL> SELECT MAX (t.id) KEEP (DENSE_RANK LAST ORDER BY t.a) AS id,
2 MAX(t.a) AS a,
3 t.b AS b,
4 t.c AS c,
5 MAX (t.d) KEEP (DENSE_RANK LAST ORDER BY t.a) AS d,
6 MAX (t.e) KEEP (DENSE_RANK LAST ORDER BY t.a) AS e
7 FROM tab t
8 GROUP BY t.b, t.c
9 ORDER BY t.b, t.c;
ID A B C D E
---------- ---------- - - ---------------- ----------------
3 2007/06/21 1 1 rfd rfv
9 2007/06/25 1 2 cvb zxc
10 2007/06/11 2 1 plm okm
8 2007/06/15 2 2 cvb kjh
что не так?
del
INSERT INTO TAB ( ID, A, B, C, D, E ) VALUES (11, TO_Date( '06/21/2007 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM' '1', '1', 'rfv', 'rfd');
с различными значениям поля a

Знаю только, что два варианта с аналитическими функциями, приведённые мною выше - одинаковы. А вот как они в сравнении с выборкой максимального значения в подзапросе - не знаю.
Про DENSE_RANK нашел, а про keep нет
Оставить комментарий
wwoland
Пусть есть таблица с полями a,b,cвыборка идет по полям c и b, допустим.
Некоторым значениям c и b соответствует много записей с различными значениям поля a.
Нужно выбрать из них запись с максимальным значением поля a.
Какое простейшее решение этой задачи.
Она довольно стандартная, навернякак для нее есть какие то простые методы(кроме выборки максимально значения поля a в подзапросе и фильтрации по нему)