2016-12-02 7 views
1

У меня есть следующие таблицы: costsКак вернуть все строки с значением MAX, удовлетворяющим условию другого поля в SQL?

+--------+------+-----------+ 
| Year | ID | Amount | 
+--------+------+-----------+ 
| 1960 | 1 | 100  | 
| 1960 | 2 | 200  | 
| 1960 | 3 | 200  | 
| 1960 | 4 | 150  | 
| 1961 | 1 | 300  | 
| 1961 | 2 | 200  | 
| 1961 | 3 | 100  | 
| 1961 | 4 | 300  |  
+---------+------+----------+ 

Я хочу все идентификаторы, имеющие MAX Суммы по годам. К примеру, за 1960, я хочу, строки с идентификаторами 2 и 3. За 1961 год я хочу строки с идентификаторами 1 и 4.

SELECT Year, ID, Amount FROM costs WHERE Amount = (SELECT MAX(Amount) FROM costs); 

выше получает меня все максимальные значения за все годы. Но я хочу условие, которое дает мне максимальное количество значений в год. Как добавить условие только для выбора записей с Year = 1960?

+0

Что DB платформы? – OldProgrammer

+0

localhost using phpMyAdmin – user2140857

+0

Я только проверил два из нижеприведенных ответов, и оба работали нормально. Не уверен, какое из представленных решений будет выполняться быстрее. Помимо секундомера, у меня нет инструментов для заметок и т. Д. Скорость для меня не проблема. Это всего лишь одно время, которое может быть сделано раз в месяц. – user2140857

ответ

1

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

SELECT c1.* 
FROM costs c1 
INNER JOIN 
(
    SELECT Year, MAX(Amount) AS MaxAmount 
    FROM costs 
    GROUP BY Year 
) c2 
    ON c1.Year = c2.Year  AND 
     c1.Amount = c2.MaxAmount 

Другой способ сделать это было бы использовать коррелированные подзапросы:

SELECT c1.* 
FROM costs c1 
WHERE c1.Amount = (SELECT MAX(c2.Amount) FROM costs c2 WHERE c2.Year = c1.Year) 

Я ожидаю, что присоединение (первый варианта) будет самым быстрым методом для больших таблиц, особенно если у вас есть соответствующие показатели будет может быть использован.

+0

Я нашел, что INNER JOIN должен быть быстрее. Он собирает все годы. У меня есть следующий вопрос. У меня есть другое поле, которое я бы хотел проверить. Назовем его регионом. В каждом регионе есть число. Теперь я хочу получить данные с областью> 5. Где я могу добавить проверку области? – user2140857

0
SELECT Year , ID , Amount 
FROM #Table T1 
JOIN 
(
    SELECT MAX(Amount) Amount,Year 
    FROM #Table 
    GROUP BY Year 
) A ON A.Year = T1.Year AND A.Amount = T1.Amount 
2

Попробуйте это .... Он должен работать

SELECT 
    * 
FROM 
    costs 
WHERE 
    (YEAR, amount) IN (
     SELECT 
      YEAR, 
      max(amount) 
     FROM 
      costs 
     GROUP BY 
      YEAR 
    ); 
+0

Отлично. Проверьте это, все выглядит великолепно. Спасибо. – user2140857

+0

см. Мой ответ, который быстрее, чем ваш принимающий ответ. Я тестировал оба ответа. Надеюсь, мой ответ более полезен для пользователя. – Faisal

+0

@Faisal Я согласен, что этот метод может быть не быстрым, и это странный синтаксис, свойственный только MySQL. На самом деле, я думаю, что соединение будет самым быстрым методом. –

2

Пожалуйста, попробуйте это с ниже query.This тестируется. Его работа прекрасна.

Нажимая на ссылку ниже, вы можете увидеть ожидаемый результат в реальном времени, который вы хотите.

SQL Fiddle Live Demo

SELECT 
    t1.* 
FROM 
    costs t1 
WHERE 
    t1.amount = (
     SELECT 
      MAX(t2.amount) 
     FROM 
      costs t2 
     WHERE 
      t2. `year` = t1. `year` 
    ); 
+0

Да, это сработало! Спасибо. – user2140857

+0

@ user2140857 если это поможет вам любезно принять, чтобы другие могли видеть его действительным, если они наткнулись на этот похожий вопрос, это может им помочь :) хороший день – Faisal