Precisamos agrupar dados em um banco de dados Oracle e devemos obter a ProductNumber
e a Description
. O Description
precisa ser aquele com mais ocorrências dentro da tabela. Ambos são um varchar2
. Veja abaixo os dados brutos:
Número de produto | Descrição |
---|---|
abc | Produto ABC (com desconto) |
abc | Produto ABC |
abc | Produto ABC |
DEF | DEF do produto |
Resultado esperado:
Número de produto | Descrição |
---|---|
abc | Produto ABC |
DEF | DEF do produto |
Tentamos isso, mas não encontramos uma maneira de incluir o Description
com a maioria das ocorrências.
select distinct cnt1.ProductNumber
from (select COUNT(*) as total, ProductNumber
from Inventory
group by ProductNumber) cnt1,
(select MAX(total) as maxtotal, ProductNumber
from (select COUNT(*) as total, ProductNumber
from Inventory
group by ProductNumber)
group by ProductNumber) cnt2
where cnt1.total = cnt2.maxtotal;
Aqui você pode encontrar um violino .
Você sabe como poderíamos fazer isso?
Aqui está uma maneira de fazer isso usando funções de janela:
EDIT: Adicionado planos para um conjunto de dados um pouco maior, Fiddle
Consulta Verace
Consulta modificada de H. Pauwelyn
A pergunta de Lennart
Eu olhei para isso - é uma pergunta interessante (+1).
Eu também adicionei dados de amostra - é sempre difícil cobrir casos extremos, mas vale a pena olhar (dados e análise inteira no violino aqui ).
Então nós temos:
Resultado:
Formulei o seguinte SQL (mostrei os primeiros passos que me levaram à minha resposta - em parte para sua compreensão, em parte para mim! :-) ):
Resultado:
Agora, observe que meu SQL escolheu o
RST, Product RST without discount
registro onde havia uma escolha entre os doisRST
registros (com e sem desconto).Agora, você verá pelo violino que a consulta de Lennart retorna o outro
RST
registro.Você pode querer investigar isso e garantir que você recupere os registros necessários em todas as circunstâncias.
Eu também olhei para os planos para as consultas. Eu descobri como fazer isso usando o violino de um artigo de Franck Pachot aqui e o violino Oracle associado aqui .
Agora, estou longe de ser um especialista em planos da Oracle, mas dada sua semelhança, não posso dizer se a consulta de Lennart ou a minha seria a mais eficiente com um grande conjunto de dados. Eu recomendo que você teste com conjuntos de dados realistas.
O único benefício "concreto" que resulta da minha consulta é que ele pode ser usado em versões antigas de servidores que não suportam
ROW_NUMBER()
- mas até o MySQL os tem agora, então é improvável que tenha um ganho significativo! :-)ps, você notará que modifiquei ligeiramente sua consulta para usar junções ANSI da seguinte maneira:
Espero que você ache isso útil e/ou mais legível? Eu acho que o seu executa um
CROSS JOIN
e depois filtra o que pode ser problemático com grandes conjuntos de dados?