Использование GROUP BY дважды в MySQL

Моя таблица выглядит так.

Location    Head    Id  IntTime
1           AMD     1   1
2           INTC    3   3
3           AMD     2   2
4           INTC    4   4
5           AMD2    1   0
6           ARMH    5   1
7           ARMH    5   0
8           ARMH    6   1
9           AAPL    7   0
10          AAPL    7   1

Расположение - это первичный ключ. Мне нужно GROUP BY Head и Id, а когда я использую GROUP BY, мне нужно сохранить строку с наименьшим значением IntTime.

После первого идентификатора GROUP BY я должен получить (я сохраняю наименьший интервал времени)

Location    Head    Id  IntTime
2           INTC    3   3
3           AMD     2   2
4           INTC    4   4
5           AMD2    1   0
7           ARMH    5   0
8           ARMH    6   1
9           AAPL    7   0

После второй GROUP BY Head, я должен получить (я сохраняю наименьший IntTime)

Location    Head    Id  IntTime
2           INTC    3   3
3           AMD     2   2
5           AMD2    1   0
7           ARMH    5   0
9           AAPL    7   0

Когда я запускаю следующую команду, я сохраняю наименьшее значение IntTime, но строки не сохраняются.

SELECT Location, Head, Id, MIN(IntTime) FROM test 
GROUP BY Id

Кроме того, чтобы запустить вторую группу GROUP BY, я сохраняю эту таблицу и снова делаю

SELECT Location, Head, Id, MIN(IntTime) FROM test2 
GROUP BY Head

Есть ли способ объединить обе команды?

[Изменить: разъяснение] Результат не должен содержать две главы с одинаковым значением или два идентификатора с одинаковым значением. При удалении этих дубликатов следует сохранить строку с наименьшим значением IntTime.

Ответ 1

Этот запрос возвращает точные окончательные результаты, которые вы ищете (пример):

SELECT `final`.*
FROM `tableName` AS `final`
JOIN (
    SELECT `thead`.`Id`, `Head`, MIN(`intTime`) AS `min_intTime`
    FROM `tableName` AS `thead`
    JOIN (
        SELECT `Id`, MIN(intTime) as min_intTime
        FROM `tableName` AS `tid`
        GROUP BY `Id`
    ) `tid`
    ON `tid`.`Id` = `thead`.`Id`
    AND `tid`.`min_intTime` = `thead`.`intTime`
    GROUP BY `Head`
) `thead`
ON `thead`.`Head` = `final`.`Head`
AND `thead`.`min_intTime` = `final`.`intTime`
AND `thead`.`Id` = `final`.`Id`

Как это работает

Самые внутренние группы запросов Id, и возвращает Id и соответствующий MIN(intTime). Затем средние группы запросов на Head и возвращают Head и соответствующие Id и MIN(intTime). Окончательный запрос возвращает все строки после сужения. Вы можете представить окончательный (внешний) запрос как запрос в таблице только с нужными строками, чтобы вы могли выполнять дополнительные сравнения (например, WHERE final.intTime > 3).

Ответ 2

SELECT a.*
FROM test a
NATURAL JOIN
(
    SELECT c.Head, c.Id, MIN(c.IntTime) AS IntTime
    FROM test c
    NATURAL JOIN
    (
        SELECT Id, MIN(IntTime) AS IntTime
        FROM test
        GROUP BY Id
    ) d
    GROUP BY c.Head
) b
ORDER BY a.Location

Ответ 3

Если я правильно понял, вам нужны строки с наименьшими значениями int/time головой и идентификатором. Я не вижу, что получает вторая "группа за головой".

Следующее делает то, что я думаю, что вы хотите:

select t.*
from t join
     (select head, id, min(intTime) as min_intTime
      from t
      group by head, id
     ) tsum
     on tsum.head = t.head and
        tsum.id = t.id and
        tsum.min_intTime = t.intTime

Вам может потребоваться наименьшая intTime для всех значений "head". Если это так, запрос выглядит так:

select t.*
from t join
     (select head, min(intTime) as min_intTime
      from t
      group by head
     ) tsum
     on tsum.head = t.head and
        tsum.min_intTime = t.intTime

Ответ 4

Я не уверен, как результат вашего примера достиг, например, местоположения = 7 для ARMH. Попробуйте это...

SELECT MIN(Location), Head, Id, MIN(IntTime)
FROM test
GROUP BY Head, Id

Ответ 5

Использовать синтаксис UNION?

(SELECT Location, Head, Id, MIN(IntTime) FROM test 
GROUP BY Id)
UNION
(SELECT Location, Head, Id, MIN(IntTime) FROM test2 
GROUP BY Head)