Использование 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)