Агрегатные функции — получение столбцов, не включенных в предложение GROUP BY
-
20-09-2019 - |
Вопрос
У меня есть таблица с тремя полями (item_id, источник и цена).(item_id, источник и цена) вместе составляют первичный ключ.
item_id source price
------- ------- -----
1 paris 13
1 london 12
1 newyork 15
2 paris 22
2 london 15
2 newyork 14
Для каждого item_id я хочу знать самое дешевое место, где его можно получить, и цену, которую я заплачу в этом месте.В приведенном выше примере я хотел бы увидеть следующий результат:
item_id source price
------- ------- ---------
1 london 12
2 newyork 14
Есть ли простой способ сделать это, не упоминая имя таблицы дважды?Я использую MySQL, поэтому не могу использовать предложение With.
Я рассмотрел объединенное решение с двумя запросами в вопросе другого пользователя (Группируйте связанные записи, но выбирайте определенные поля только из первой записи.), но мне бы очень не хотелось дважды упоминать таблицу.Проблема в том, что простая таблица в этом вопросе на самом деле представляет собой встроенное представление в моей реальной проблеме, создание которой занимает около 5 секунд на каждое использование, поэтому я надеюсь найти альтернативы.
Решение
Вот один из способов использования внутреннего соединения для фильтрации строк с самой низкой ценой:
select i.*
from items i
inner join (
select item_id, min(price) as minprice
from items
group by item_id
) cheapest on i.price = cheapest.minprice
and i.item_id = cheapest.item_id
Если есть несколько источников с самой низкой ценой, они все появятся.
РЕДАКТИРОВАТЬ:Поскольку в вашем вопросе упоминается, что создание представления элементов занимает много времени, вы можете сохранить результат во временной таблице.
create temporary table temp_items
as
select item_id, source, price from YourView
А затем запустите запрос на группировку во временной таблице.В MySQL временная таблица видна только для текущего соединения и автоматически удаляется при закрытии соединения.
Другие советы
К сожалению, я не знаю наизусть данные MySQL и преобразование строк.Но есть кое-что, что, если вы немного помассируете правильный синтаксис, может вас удивить:
SELECT
item_id,
source = Convert(varchar(30), Substring(packed, 5, 30)),
price = Convert(int, Substring(packed, 1, 4))
FROM
(
SELECT
item_id,
Min(Convert(binary(4), price) + Convert(varbinary(30), source) AS packed
FROM items
GROUP BY item_id
) X
Это наверняка хак.Его определенно не следует использовать во всех случаях.Но когда производительность имеет решающее значение, иногда оно того стоит.
Видеть эта тема для получения дополнительной информации.