Агрегатные функции — получение столбцов, не включенных в предложение GROUP BY

StackOverflow https://stackoverflow.com/questions/1734484

Вопрос

У меня есть таблица с тремя полями (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

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

Видеть эта тема для получения дополнительной информации.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top