SQL - Dúvida no desenvolvimento de uma query
14/10/2019
0
Tenho 3 tabelas (Clientes, Produtos, Pedidos) e preciso de uma query que responda a seguinte questão: Qual produto é o mais contratado na segunda compra do cliente?
Pra tentar ilustrar melhor tabelas estão da seguinte forma:
Tabela Cliente:(id, nome)
(1, José)
(2, Renato)
(3, Luciano)
(4, Gisele)
(5, Rafael)
Tabela Produtos: (id, descricao)
(1, ''Email Marketing'')
(2, ''Hospedagem'')
(3, ''Cloud'')
Tabela pedidos:
(id, cliente_id, produto_id, valor_mensal, data_inicio, data_fim)
(1, 1, 1, 50, 2/10/2017, null)
(2, 2, 2, 29, 3/15/2017, null)
(3, 2, 3, 159, 8/22/2016, 2/17/2017)
(4, 2, 3, 250, 2/17/2017, null)
(5, 2, 1, 50, 5/15/2015, null)
(6, 3, 1, 250, 5/1/2018, null)
(7, 3, 2, 59, 2/28/2018, null)
(8, 4, 2, 29, 11/8/2015, null)
(9, 4, 2, 35, 6/5/2016, null)
(10, 4, 2, 49, 6/7/2016, null)
(11, 5, 1, 50, 9/9/2016, 1/1/2018)
(12, 5, 3, 600, 9/15/2016, null)
Bruno Feitosa
Post mais votado
16/10/2019
Você tem um código e não sabe como concluir ou resolver.
A função MAX() vai diretamente para o maior valor, então se quiser o produto mais vendido terá que usar outra abordagem.
Você vai precisar saber qual é o primeiro pedido, e identifica a partir deste ponto .
SELECT produtos.descricao AS ''Produto'', MAX(p2.produto_id) AS ''Quantidade'' FROM pedidos JOIN produtos ON produtos.id = pedidos.produto_id JOIN pedidos p2 ON produtos.id = p2.produto_id WHERE p2.produto_id = pedidos.produto_id and pedidos.id>min(pedidos.id) ;
E tem que colocar o cliente, já que resultado é por cliente
Estou sem condições de testar....
Entendi, mas você está querendo a resposta.
Bom para isto você terá que se dedicar um pouco mais.
A resposta está presente na sua lista (fato), então analise que irá solucionar.
Bons estudos para você.
Estou me dedicando. Só que como disse, estou com dificuldade nesse exercício especificamente, outros eu consegui.
Exemplo, a única coisa que consegui listar foi o serviço mais contratado no primeiro pedido, usando:
SELECT produtos.descricao AS ''Produto'', MAX(p2.produto_id) AS ''Quantidade''
FROM pedidos JOIN produtos
ON produtos.id = pedidos.produto_id
JOIN pedidos p2
ON produtos.id = p2.produto_id
WHERE p2.produto_id = pedidos.produto_id;
Não estou conseguindo fazer isso pra me retornar o produto mais vendido a partir do 2º pedido. Perguntei aqui justamente pra ter a resposta e justamente com ela ver a lógica e onde estou errando pra aprender e fazer nas próximas.
Obrigado!
Luiz Vichiatto
Mais Posts
16/10/2019
Luiz Vichiatto
Entendi, mas você está querendo a resposta.
Bom para isto você terá que se dedicar um pouco mais.
A resposta está presente na sua lista (fato), então analise que irá solucionar.
Bons estudos para você.
16/10/2019
Bruno Feitosa
Entendi, mas você está querendo a resposta.
Bom para isto você terá que se dedicar um pouco mais.
A resposta está presente na sua lista (fato), então analise que irá solucionar.
Bons estudos para você.
Estou me dedicando. Só que como disse, estou com dificuldade nesse exercício especificamente, outros eu consegui.
Exemplo, a única coisa que consegui listar foi o serviço mais contratado no primeiro pedido, usando:
SELECT produtos.descricao AS 'Produto', MAX(p2.produto_id) AS 'Quantidade'
FROM pedidos JOIN produtos
ON produtos.id = pedidos.produto_id
JOIN pedidos p2
ON produtos.id = p2.produto_id
WHERE p2.produto_id = pedidos.produto_id;
Não estou conseguindo fazer isso pra me retornar o produto mais vendido a partir do 2º pedido. Perguntei aqui justamente pra ter a resposta e justamente com ela ver a lógica e onde estou errando pra aprender e fazer nas próximas.
Obrigado!
16/10/2019
Emerson Nascimento
Na segunda compra ou a partir da segunda compra?
16/10/2019
Bruno Feitosa
Na segunda compra ou a partir da segunda compra?
Pelo enunciado, é só na segunda compra, mas de qualquer forma to tentando fazer para os 2 casos.
Os resultados teriam que ser:
Na segunda compra:
Hospedagem | 2
Cloud | 2
A partir da segunda compra:
Hospedagem | 3
Cloud | 3
Eu tentei isso para o caso de 'a partir da segunda compra' :
SELECT produtos.descricao AS 'Produto', MAX(pedidos.produto_id) AS 'Quantidade'
FROM pedidos JOIN produtos
ON produtos.id = pedidos.produto_id
JOIN pedidos p2
ON p2.id <> pedidos.id;
Mas ele só retorna o registro Hospedagem | 3, sendo que o Cloud tem a mesma quantidade de contratações.
18/10/2019
Emerson Nascimento
SELECT pr.id, pr.descricao FROM b_feitosa_produtos pr JOIN b_feitosa_pedidos p on p.produto_id = pr.id WHERE p.id > (select min(p2.id) primeira from b_feitosa_pedidos p2 where p2.cliente_id = p.cliente_id ) GROUP BY pr.id, pr.descricao HAVING count(pr.id) = (select top 1 count(*) from b_feitosa_pedidos p2 where p2.id > ( select min(p3.id) primeira from b_feitosa_pedidos p3 where p3.cliente_id = p2.cliente_id ) group by p2.produto_id order by count(*) desc)
produtos mais vendidos a partir da segunda compra do cliente:
SELECT p.cliente_id, c.nome, p.produto_id, pr.descricao, sum(p.valor_mensal) valor FROM b_feitosa_pedidos p JOIN b_feitosa_cliente c ON c.id = p.cliente_id JOIN b_feitosa_produtos pr ON pr.id = p.produto_id WHERE p.id > (select min(p3.id) primeira from b_feitosa_pedidos p3 where p3.cliente_id = p.cliente_id ) and p.produto_id = (select top 1 p3.produto_id maisvendido from b_feitosa_pedidos p3 where p3.cliente_id = p.cliente_id and p3.id > ( select min(p4.id) primeira from b_feitosa_pedidos p4 where p4.cliente_id = p3.cliente_id ) group by p3.produto_id order by count(*) desc) group by p.cliente_id, c.nome, p.produto_id, pr.descricao order by p.cliente_id
20/10/2019
Bruno Feitosa
Tenho 3 tabelas (Clientes, Produtos, Pedidos) e preciso de uma query que responda a seguinte questão: Qual produto é o mais contratado na segunda compra do cliente?
Pra tentar ilustrar melhor tabelas estão da seguinte forma:
Tabela Cliente:(id, nome)
(1, José)
(2, Renato)
(3, Luciano)
(4, Gisele)
(5, Rafael)
Tabela Produtos: (id, descricao)
(1, ''''Email Marketing'''')
(2, ''''Hospedagem'''')
(3, ''''Cloud'''')
Tabela pedidos:
(id, cliente_id, produto_id, valor_mensal, data_inicio, data_fim)
(1, 1, 1, 50, 2/10/2017, null)
(2, 2, 2, 29, 3/15/2017, null)
(3, 2, 3, 159, 8/22/2016, 2/17/2017)
(4, 2, 3, 250, 2/17/2017, null)
(5, 2, 1, 50, 5/15/2015, null)
(6, 3, 1, 250, 5/1/2018, null)
(7, 3, 2, 59, 2/28/2018, null)
(8, 4, 2, 29, 11/8/2015, null)
(9, 4, 2, 35, 6/5/2016, null)
(10, 4, 2, 49, 6/7/2016, null)
(11, 5, 1, 50, 9/9/2016, 1/1/2018)
(12, 5, 3, 600, 9/15/2016, null)
Vim só agradecer a ajuda de vocês! Com as dicas daqui e com algumas outras que fui pegando em outros lugares, fiz dessa forma e deu certo:
SELECT DISTINCT
*
FROM
(
SELECT
pr.descricao Produto
, ROW_NUMBER() OVER(PARTITION BY p.cliente_id ORDER BY p.data_inicio) Quantidade
FROM
pedidos p
JOIN
clientes c
ON p.cliente_id = c.id
JOIN
produtos pr
ON p.produto_id = pr.id
) X
WHERE
Quantidade = 2;
Mais uma vez, obrigado pela ajuda!
20/10/2019
Emerson Nascimento
SELECT DISTINCT
*
FROM
(
SELECT
pr.descricao Produto
, ROW_NUMBER() OVER(PARTITION BY p.cliente_id ORDER BY p.data_inicio) Quantidade
FROM
pedidos p
JOIN
clientes c
ON p.cliente_id = c.id
JOIN
produtos pr
ON p.produto_id = pr.id
) X
WHERE
Quantidade = 2;
A forma acima funciona mesmo?
Além de você não estar pegando a quantidade (está pegando o número da linha), está pegando uma "quantidade" indicada por você.
20/10/2019
Bruno Feitosa
SELECT DISTINCT
*
FROM
(
SELECT
pr.descricao Produto
, ROW_NUMBER() OVER(PARTITION BY p.cliente_id ORDER BY p.data_inicio) Quantidade
FROM
pedidos p
JOIN
clientes c
ON p.cliente_id = c.id
JOIN
produtos pr
ON p.produto_id = pr.id
) X
WHERE
Quantidade = 2;
A forma acima funciona mesmo?
Além de você não estar pegando a quantidade (está pegando o número da linha), está pegando uma "quantidade" indicada por você.
Nos testes que fiz, estava me retornando o resultado 'esperado'. Porém, levando em conta suas observações resolvi fazer novos testes, incluindo uma nova segunda compra que mudaria o resultado que deveria ser apresentado, mas realmente não funcionou.
O que tenho:
SELECT
*
FROM
(
SELECT
pr.descricao Produto
,ROW_NUMBER() OVER(PARTITION BY p.cliente_id ORDER BY p.id) XRANK
FROM
pedidos p
JOIN
clientes c
ON p.cliente_id = c.id
JOIN
produtos pr
ON p.produto_id = pr.id
) X
WHERE
XRANK = 2;
Usando essa query, consigo trazer todas as segundas compras de cada cliente, mas não encontrei uma forma de trazer somente o produto mais comprado.
Exemplo, com a tabela que tenho, são 3 Hospedagens e 2 Clouds vendidos na segunda compra. Isso a query acima me mostra. O que eu preciso é que ela mostre somente o produto que aparece mais vezes, nesse caso a hospedagem.
21/10/2019
Emerson Nascimento
produtos mais vendidos a partir da segunda compra:
SELECT pr.id, pr.descricao FROM b_feitosa_produtos pr JOIN b_feitosa_pedidos p on p.produto_id = pr.id WHERE p.id > (select min(p2.id) primeira from b_feitosa_pedidos p2 where p2.cliente_id = p.cliente_id ) GROUP BY pr.id, pr.descricao HAVING count(pr.id) = (select top 1 count(*) from b_feitosa_pedidos p2 where p2.id > ( select min(p3.id) primeira from b_feitosa_pedidos p3 where p3.cliente_id = p2.cliente_id ) group by p2.produto_id order by count(*) desc)
produtos mais vendidos a partir da segunda compra do cliente:
SELECT p.cliente_id, c.nome, p.produto_id, pr.descricao, sum(p.valor_mensal) valor FROM b_feitosa_pedidos p JOIN b_feitosa_cliente c ON c.id = p.cliente_id JOIN b_feitosa_produtos pr ON pr.id = p.produto_id WHERE p.id > (select min(p3.id) primeira from b_feitosa_pedidos p3 where p3.cliente_id = p.cliente_id ) and p.produto_id = (select top 1 p3.produto_id maisvendido from b_feitosa_pedidos p3 where p3.cliente_id = p.cliente_id and p3.id > ( select min(p4.id) primeira from b_feitosa_pedidos p4 where p4.cliente_id = p3.cliente_id ) group by p3.produto_id order by count(*) desc) group by p.cliente_id, c.nome, p.produto_id, pr.descricao order by p.cliente_id
22/10/2019
Bruno Feitosa
produtos mais vendidos a partir da segunda compra:
SELECT pr.id, pr.descricao FROM b_feitosa_produtos pr JOIN b_feitosa_pedidos p on p.produto_id = pr.id WHERE p.id > (select min(p2.id) primeira from b_feitosa_pedidos p2 where p2.cliente_id = p.cliente_id ) GROUP BY pr.id, pr.descricao HAVING count(pr.id) = (select top 1 count(*) from b_feitosa_pedidos p2 where p2.id > ( select min(p3.id) primeira from b_feitosa_pedidos p3 where p3.cliente_id = p2.cliente_id ) group by p2.produto_id order by count(*) desc)
produtos mais vendidos a partir da segunda compra do cliente:
SELECT p.cliente_id, c.nome, p.produto_id, pr.descricao, sum(p.valor_mensal) valor FROM b_feitosa_pedidos p JOIN b_feitosa_cliente c ON c.id = p.cliente_id JOIN b_feitosa_produtos pr ON pr.id = p.produto_id WHERE p.id > (select min(p3.id) primeira from b_feitosa_pedidos p3 where p3.cliente_id = p.cliente_id ) and p.produto_id = (select top 1 p3.produto_id maisvendido from b_feitosa_pedidos p3 where p3.cliente_id = p.cliente_id and p3.id > ( select min(p4.id) primeira from b_feitosa_pedidos p4 where p4.cliente_id = p3.cliente_id ) group by p3.produto_id order by count(*) desc) group by p.cliente_id, c.nome, p.produto_id, pr.descricao order by p.cliente_id
Tentei sim, mas em ambos os casos está apresentando erro de sintaxe no MS SQL Server 2017 no uso do TOP. Já tentei corrigir, mas ainda não consegui, então não sei se deu certo.
22/10/2019
Emerson Nascimento
22/10/2019
Bruno Feitosa
SELECT
p.cliente_id, c.nome,
p.produto_id, pr.descricao,
sum(p.valor_mensal) valor
FROM
pedidos p
JOIN
clientes c ON c.id = p.cliente_id
JOIN
produtos pr ON pr.id = p.produto_id
WHERE
p.id > (select min(p3.id) primeira
from pedidos p3
where p3.cliente_id = p.cliente_id)
and p.produto_id =
(select p3.produto_id, TOP 1 p3.produto_id maisvendido
from pedidos p3
where p3.cliente_id = p.cliente_id
and p3.id > ( select min(p4.id) primeira
from pedidos p4
where p4.cliente_id = p3.cliente_id )
group by p3.produto_id
order by count(*) desc)
group by
p.cliente_id, c.nome,
p.produto_id, pr.descricao
order by
p.cliente_id
Erro: Incorrect syntax near the keyword 'TOP'.
22/10/2019
Emerson Nascimento
select p3.produto_id, TOP 1 p3.produto_id maisvendido
o correto é:
select TOP 1 p3.produto_id maisvendido
22/10/2019
Bruno Feitosa
select p3.produto_id, TOP 1 p3.produto_id maisvendido
o correto é:
select TOP 1 p3.produto_id maisvendido
Obrigado, Emerson! Arrumei e deu certo.
Acabei de testar a outra query que você havia mandado e ela era o que eu precisava!
SELECT
pr.descricao Produto
FROM
produtos pr
JOIN
pedidos p on p.produto_id = pr.id
WHERE
p.id > (select min(p2.id) primeira
from pedidos p2
where p2.cliente_id = p.cliente_id )
GROUP BY
pr.id,
pr.descricao
HAVING
count(pr.id) = (select top 1 count(*)
from pedidos p2
where p2.id > ( select min(p3.id) primeira
from pedidos p3
where p3.cliente_id = p2.cliente_id )
group by p2.produto_id
order by count(*) desc)
Fiz uns testes incluindos novos clientes e pedidos e tá tudo ok!
Minha última dúvida é se no Select, junto com o nome do produto (pr.descricao), eu consigo mostrar a quantidade de vezes que aquele produto foi comprado na segunda compra?
22/10/2019
Emerson Nascimento
SELECT pr.descricao Produto, count(pr.id) Qtd FROM [....]
Clique aqui para fazer login e interagir na Comunidade :)