Funções agregadas - Colunas não incluídas no grupo por cláusula
-
20-09-2019 - |
Pergunta
Eu tenho uma tabela que possui três campos (item_id, origem e preço). (item_id, origem e preço) juntos compõem a chave primária.
item_id source price
------- ------- -----
1 paris 13
1 london 12
1 newyork 15
2 paris 22
2 london 15
2 newyork 14
Para cada item_id, quero saber o lugar mais barato para obtê -lo e o preço que pagarei naquele local. Para o exemplo acima, gostaria de ver a seguinte saída:
item_id source price
------- ------- ---------
1 london 12
2 newyork 14
Existe uma maneira simples de fazer isso sem mencionar o nome da tabela duas vezes? Estou usando o MySQL, então não posso usar uma cláusula com.
Eu dei uma olhada na solução de duas margens unida na pergunta de outro usuário (Registros relacionados ao grupo, mas escolha certos campos apenas do primeiro registro), mas eu realmente gostaria de evitar mencionar a mesa duas vezes. O problema é que a tabela simples desta questão realmente representa uma visão em linha no meu problema real, que leva cerca de 5 segundos para criar por uso, por isso espero encontrar alternativas.
Solução
Aqui está uma maneira, usando uma junção interna para filtrar linhas com o menor preço:
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
Se houver várias fontes com o menor preço, todas elas aparecerão.
EDIT: Como sua pergunta menciona a visualização de itens para aumentar, você pode armazenar o resultado em uma tabela temporária.
create temporary table temp_items
as
select item_id, source, price from YourView
E depois execute a consulta de agrupamento na tabela temporária. No MySQL, uma tabela temporária é visível apenas para a conexão atual e é descartada automaticamente quando a conexão é fechada.
Outras dicas
Infelizmente, não conheço dados MySQL e conversão de string de cor. Mas aqui está algo que, se você massageou um pouco para a sintaxe correta, poderá surpreendê -lo:
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
Isso certamente é um hack. Definitivamente, não deve ser usado em todos os casos. Mas quando o desempenho é crítico, às vezes vale a pena.
Ver este tópico para mais informações.