MySQL запрос, который нуждается в большой (сложной?) Фильтрации - PullRequest
1 голос
/ 08 января 2012

У меня есть следующая таблица базы данных (Люди):

+--------+--------+--------+
|  Name  |   Age  |  Time  |
+--------+--------+--------+
| Tim    |   30   |  10:10 |
| Jill   |   31   |  10:20 |
| Peter  |   31   |  10:30 |
| Peter  |   33   |  10:40 |
| Jack   |   32   |  10:50 |
| Susan  |   35   |  10:60 |
| Susan  |   35   |  11:70 |
+--------+--------+--------+ 

Теперь я хочу получить 5 имен, которые являются самыми старыми из этого списка:

Select * FROM People ORDER BY Age DESC LIMIT 5

Это даст:

| Susan  |   35   |  11:70 |
| Susan  |   35   |  10:60 |
| Peter  |   33   |  10:40 |
| Jack   |   32   |  10:50 |
| Peter  |   31   |  10:30 |

Теперь это не совсем то, что я хочу. Мы видим Сьюзен там дважды, так же, как Питер. Я не хочу, чтобы повторяющиеся имена появлялись. Теперь мы видим, что 2 Сьюзен имеют оба одинакового возраста, поэтому Сьюзен с самым высоким временем (mm:ss) должна быть отфильтрована (в данном случае: | Susan | 35 | 11:70 |)

Для 2 Петров мы видим, что один Петр старше, поэтому в этом случае младший Петр должен быть отфильтрован (| Peter | 31 | 10:30 |)

Так как бы выглядел этот Запрос? Сначала он должен выбрать все, затем упорядочить их по возрасту (самый старый сверху), затем отфильтровать дубликаты имен, где он должен сначала посмотреть на возраст (самый низкий фильтруется), а затем по времени (самое высокое время будет отфильтровано), а затем DESC LIMIT 5.

Таким образом, единственный правильный результат будет выглядеть так:

| Susan  |   35   |  10:60 |
| Peter  |   33   |  10:40 |
| Jack   |   32   |  10:50 |
| Jill   |   31   |  10:20 |
| Peter  |   31   |  10:30 |

Ответы [ 3 ]

2 голосов
/ 08 января 2012
SELECT
    Name, Age, MIN(Time) As LowestTime
FROM
    People
GROUP BY 
    Name, Age
ORDER BY
    Age DESC, Name ASC
LIMIT 5
1 голос
/ 08 января 2012
SELECT Name,Age,Max(Time) as Time
FROM People
GROUP BY concat(Age,':',Name)
ORDER BY Age DESC,Time ASC 
LIMIT 5

GROUP BY заботится о Сьюзен, ЗАКАЗАТЬ ПИТЕРА

0 голосов
/ 08 января 2012

Я считаю, что этот запрос - то, что вы ищете.Он фильтрует по имени: возрасту, затем по имени: времени и, наконец, создает окончательную группу по имени и ORDER при необходимости.

Запрос

SELECT `Name`, `Age`, `Time`
FROM `People`
WHERE concat(`Name`,'-',`Time`)
 IN (
  SELECT concat(`Name`,'-',MAX(`Time`))
  FROM `People`
  WHERE concat(`Name`,'-',`Age`)
  IN (
   SELECT concat(`Name`,'-',MIN(`Age`))
   FROM `People`
   GROUP BY `Name`
  )
  GROUP BY `Name`
 )
 GROUP BY `Name`
 ORDER BY `Age` DESC
 LIMIT 5

Примечание: Хотя это правильный запрос и он возвращает результаты, которые вы ищете, он может быть довольно дорогим, особенно с таблицей большего размера.Если вы планируете выполнить эту фильтрацию для таблицы большего размера, я бы предложил добавить столбец, в котором вы объединяете эти поля вручную, и настроить индекс для обоих столбцов.Кроме того, я предполагаю, что это был только быстрый пример, но если вам также нужно настроить столбец id, который будет PRIMARY и auto_increment.

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