Как использовать max () в SQL - PullRequest
       15

Как использовать max () в SQL

1 голос
/ 01 октября 2011

У меня есть таблица, которая выглядит следующим образом:

col1   col2  col3  
------ ----- ----- 
A      1     trout
A      2     trout
B      1     bass
C      1     carp
C      2     tuna
D      1     salmon

Я действительно хочу выбрать только строки с максимальным значением для col2.

Запрос, который я хочу сгенерировать, вернул быследующее:

col1   col2  col3  
------ ----- ----- 
A      2     trout
B      1     bass
C      2     tuna
D      1     salmon

Я пробовал что-то вроде этого:

select col1, max (col2) as mCol2, col3
from mytable
group by col1, col2

В этом случае я получаю:

col1   Mcol2 col3  
------ ----- ----- 
A      2     trout
B      1     bass
C      1     carp
C      2     tuna
D      1     salmon

Как видите, явсе еще получаю C, 1, carp, когда я только хочу C, 2, tuna.

Я подумал о попытке сделать что-то вроде

select col1, col2, col3
from mytable
where 
    col1-n-col2 in (
        select col1, max (col2) as mCol2
        from mytable)
group by col1, col2

Но я не думаю, что это законно в SQL,Какое очевидное решение я упустил?

Ответы [ 7 ]

7 голосов
/ 01 октября 2011

Если (col1, col2) уникален или если вы не возражаете против дубликатов в случае связей:

SELECT T1.col1, T1.col2, T1.col3
FROM mytable T1
JOIN (
    SELECT col1, MAX (col2) AS mCol2
    FROM mytable
    GROUP BY col1
) T2
ON T1.col1 = T2.col1
AND T1.col2 = T2.mCol2

Если вы хотите выбрать любую строку в случае связи (требуется поддержка ROW_NUMBER, т.е. не MySQL):

SELECT col1, col2, col3
FROM (
     SELECT
         col1, col2, col3,
         ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2 DESC) AS rn
     FROM mytable
) T1
WHERE rn = 1
3 голосов
/ 02 октября 2011

Аналитические функции, безусловно, являются лучшим способом решения такого рода проблем, поскольку они будут работать намного лучше, чем подзапрос для большого набора данных.

Либо попробуйте второй запрос, предоставленный Марком Байерсом, либо попробуйте запрос, показанный ниже:

select 
  col1, 
  max (col2) as mCol2, 
  max (col3) keep (dense_rank last order by col2) as col3
from mytable
group by col1

При этом используется аналитическая функция LAST , чтобы получить последнее значение в каждой группе после упорядочения по col2. MAX, используемый для col3, требуется синтаксисом, но на самом деле является только тай-брейком.

1 голос
/ 01 октября 2011

Вы не указали какую базу данных вы используете - на SQL Server и некоторых других вы можете использовать CTE (Common Table Expression) с функцией управления окнами для получения ваших строк:

;WITH HighestOnly AS
(
   SELECT
       col1, col2, col3,
       ROW_NUMBER() OVER(PARTITION BY col1 ORDER BY col2 DESC) AS 'RowNum'
   FROM 
       MyTable
) 
SELECT 
   col1, col2, col3
FROM
   HighestOnly
WHERE 
   RowNum = 1

Это «разделит» ваши данные по указанным критериям (col1) и выведет последовательные числа для каждого раздела данных, начиная с одного - по второму заданному критерию (col2 DESC). Таким образом, для каждого «раздела» данных строка с наибольшим значением в col2 будет иметь RowNum = 1 - и это то, что я выбираю здесь.

1 голос
/ 01 октября 2011

вы были близки

select t.col1, t.col2, t.col3
from mytable t,
    (select col1, 
        max (col2) as mx 
    from mytable
    group by col1) m
where m.col1 = t.col1
and m.mx = t.col2
0 голосов
/ 01 октября 2011

hei ..

У меня не установлена ​​база данных Oracle, но для MySQL это неправильно ..

Это из-за вашего пространства в синтаксисе ... правильная версия

SELECT MAX(column) ...

, а не

SELECT MAX (column) ...

Я не думаю, что с пробелом распознается как функция ...

0 голосов
/ 01 октября 2011

Вот один подход

With max_qry as
(select col1, max(col2) as mcol2 from mytable group by col1)
select m.col1, m.col2, m.col3
from mytable m join max_qry on m.col1 = mq.col1 and m.col2 = mq.mcol2
0 голосов
/ 01 октября 2011

Попробуйте

    select mytable.col1, mytable.col2, mytable.col3
    from mytable
    join 
     ( select col1, max(col2) as col2
       from mytable 
       group by col1) as mytablemax
    on  mytable.col1 = mytablemax.col1 
    and mytable.col2 = mytablemax.col2
...