2015-11-13 5 views
0

У меня возникла проблема с извлечением строки с максимальным значением большой группы в oracle db.выберите строки с максимальным значением из группы

мой стол выглядит как-то вроде этого:

ид, col1, col2, COL3, COL4, col5, date_col

Группа будет состоять из 4-х колонок col1, col2, col3, COL4, так что члены mof группы должны быть равны в этих полях, и из каждой группы мне нужны строки (id достаточно) с максимальным значением date_col (их может быть несколько с той же датой).

Должно ли быть разрешено каким-либо образом с группой или, возможно, существует лучший подход?

Спасибо за советы!

Приветствия

ответ

2

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

SQL Fiddle

Oracle 11g R2 Схема установки:

CREATE TABLE table_name (id, col1, col2, col3, col4, col5, date_col) AS 
      SELECT 1, 1, 1, 1, 1, 1, DATE '2015-11-13' FROM DUAL 
UNION ALL SELECT 2, 1, 1, 1, 1, 2, DATE '2015-11-12' FROM DUAL 
UNION ALL SELECT 3, 1, 1, 1, 1, 3, DATE '2015-11-11' FROM DUAL 
UNION ALL SELECT 4, 1, 1, 1, 1, 4, DATE '2015-11-13' FROM DUAL 
UNION ALL SELECT 5, 1, 1, 1, 1, 5, DATE '2015-11-12' FROM DUAL 
UNION ALL SELECT 5, 1, 1, 1, 1, 5, DATE '2015-11-12' FROM DUAL 
UNION ALL SELECT 6, 1, 1, 1, 2, 1, DATE '2015-11-12' FROM DUAL 
UNION ALL SELECT 7, 1, 1, 1, 2, 2, DATE '2015-11-13' FROM DUAL 
UNION ALL SELECT 8, 1, 1, 1, 2, 3, DATE '2015-11-11' FROM DUAL 
UNION ALL SELECT 9, 1, 1, 1, 2, 4, DATE '2015-11-12' FROM DUAL 
UNION ALL SELECT 10, 1, 1, 1, 2, 5, DATE '2015-11-13' FROM DUAL 

Запрос 1:

SELECT * 
FROM (
    SELECT t.*, 
     RANK() OVER (PARTITION BY col1, col2, col3, col4 ORDER BY date_col DESC) AS rnk 
    FROM table_name t 
) 
WHERE rnk = 1 

Results:

| ID | COL1 | COL2 | COL3 | COL4 | COL5 |     DATE_COL | RNK | 
|----|------|------|------|------|------|----------------------------|-----| 
| 1 | 1 | 1 | 1 | 1 | 1 | November, 13 2015 00:00:00 | 1 | 
| 4 | 1 | 1 | 1 | 1 | 4 | November, 13 2015 00:00:00 | 1 | 
| 7 | 1 | 1 | 1 | 2 | 2 | November, 13 2015 00:00:00 | 1 | 
| 10 | 1 | 1 | 1 | 2 | 5 | November, 13 2015 00:00:00 | 1 | 
+0

очень подробный ответ, спасибо –

0

Как насчет:

SELECT MAX(ColumnName) FROM Dual; 

Edit:
Я думаю, что вы должны работать с видами, чтобы получить то, что вы хотели.
У меня нет oppertunity, чтобы проверить этот код, но я думаю, что нужно что-то вроде этого:

-- ViewA 
SELECT NULL Id, Col1, Col2, Col3, Col4, Col5, MAX(DateCol) 
FROM TableA 
GROUP BY Col1, Col2, Col3, Col4, Col5 

-- ViewB 
SELECT Id, Col1, Col2, Col3, Col4, Col5, DateCol 
FROM TableA 

-- ViewC 
SELECT NVL(A.Id, B.Id) Id, 
    A.Col1, 
     A.Col2, 
     A.Col3, 
     A.Col4, 
     A.Col5, 
     A.DateCol 
FROM ViewA A, ViewB B 
AND  A.Col1 = B.Col1 
AND A.Col2 = B.Col2 
AND A.Col3 = B.Col3 
AND  A.Col4 = B.Col4; 
0

это то, что вы ищете ..........

SELECT col1, col2, col3, col4, MAX(date_col), Count(id) 
FROM YOUR_TABLE 
WHERE 1=1 
    AND any other condition 
GROUP BY 
    col1, col2, col3, col4 
+0

Проблема в том, что таким образом я не получаю Ид-е, но мне они нужны, извините, если описание не было ясно, достаточно –

2

Я думаю, что вам нужна условная агрегация с row_number():

select t.* 
from (select t.*, 
      row_number() over (partition by col1, col2, col3, col4 order by date_col desc) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

Если вы хотите, чтобы все строки с максимальным значением, а затем использовать dense_rank() или rank().

Вы также можете использовать keep, чтобы получить значение col5 с помощью агрегации:

select col1, col2, col3, col4, 
     max(col5) keep (dense_rank first order by date_col desc) as col5, 
     max(date_col) as date_col 
from t 
group by col1, col2, col3, col4; 

Однако это возвращает только одно значение.

+0

Это решение довольно близко, но на самом деле, как я уже упоминал, есть несколько записей с таким же максимальным значением в «группе», и мне нужны все они, но это, кажется, возвращает только 1 результат/группу –

+0

@MahendarMahi T вы получите все строки вместо одной строки, содержащей максимальное значение (или одно из максимальных значений). – MT0

+1

@ erik.c. , , Затем вы просто используете 'rank()' или 'dense_rank()'. –

-1
select T.id 
    from table_name T 
where date_col = (select max(date_col) 
        from table_name 
        where col1 = T.col1) 
group by col1; 

Попробуйте это решение

+0

Недопустимый SQL. (GROUP BY issues ...) – jarlh

+0

выберите отдельный col1, T.ID from table_name T где date_col = (выберите max (date_col) from table_name где col1 = T.col1); – Khazratbek

+0

надеюсь, что это поможет. Если нет, сообщите мне о дистанционном контроле, и я попытаюсь исправить вашу проблему. – Khazratbek