query mysql para curva ABC

Forum sobre SQL.

Moderador: Moderadores

alexlucc
Usuário Nível 1
Usuário Nível 1
Mensagens: 49
Registrado em: 13 Nov 2016 19:19
Localização: Nova Iguaçu /rj

query mysql para curva ABC

Mensagem por alexlucc »

Bom dia amigos,

Estou desenvolvendo uma query para relatório da curva abc dos produtos. Estou enfrentenado dificuldade para fazer o acumulado dos percentuais para depois a aplicar a classificação "A", "B" ou "C". Se algum tiver alguma idéia fico grato.

Código: Selecionar todos

SET @totger = (SELECT SUM(CAST(subtot AS DECIMAL(15,3))) FROM itemvendas) ;
SELECT 
    d1.codbar,
    d1.valor_item,
    d1.prod,
    @totger as total_geral,
   (CAST(d1.valor_item AS DECIMAL(15,3)) / @totger) * 100 perc 

FROM (

SELECT 
     d.codbar,
     d.valor_item,
     d.prod,
     @totger as total_geral,
 (CAST(d.valor_item AS DECIMAL(15,3)) / @totger) * 100 perc
 
FROM ( 	
SELECT
    ni.codbar,
    SUM(ni.subtot) AS valor_item, pro.nomcom AS prod
FROM itemvendas ni
INNER JOIN produtos pro ON pro.codbar = ni.codbar
	
GROUP BY ni.codbar
ORDER BY 2 DESC ) d ) d1
Anexos
curvaabc_query.JPG
Editado pela última vez por JoséQuintas em 07 Jul 2022 19:31, em um total de 1 vez.
Razão: Mensagem editada para colocar a tag [ code ]<br>Veja como utilizar esta tag: http://www.pctoledo.com.br/forum/faq.php?mode=bbcode#f2r1
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

query mysql para curva ABC

Mensagem por JoséQuintas »

Esse confunde, ainda mais que curva ABC não tem um modo padrão de ser calculado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

query mysql para curva ABC

Mensagem por alxsts »

Olá!
JoséQuintas escreveu:Esse confunde, ainda mais que curva ABC não tem um modo padrão de ser calculado.
Sem conhecer as tabelas, fica mais difícil ainda... e sem conhecer como quer calcular a curva, mais difícil ainda...

Veja este artigo: Como fazer curva ABC? Veja o passo a passo e aplique em seu negócio

Use a tag [ code ] para postar código fonte. Veja aqui como utilizar.
[]´s
Alexandre Santos (AlxSts)
Fernando queiroz
Usuário Nível 4
Usuário Nível 4
Mensagens: 779
Registrado em: 13 Nov 2014 00:41
Localização: Porto Alegre/RS

query mysql para curva ABC

Mensagem por Fernando queiroz »

HARBOUR 3.2, HWGUI 2.23 B3, SEFAZCLASS, PDFClass, ADO + MariaDB/MySQL, RMChart
Fernando queiroz
Usuário Nível 4
Usuário Nível 4
Mensagens: 779
Registrado em: 13 Nov 2014 00:41
Localização: Porto Alegre/RS

query mysql para curva ABC

Mensagem por Fernando queiroz »

Solucao para o caso, agora é somente adaptação para o seu caso

Código: Selecionar todos

SET @PER_ACUMULADO := 0 ;
SET @SOMA_1 := 0 ;
SET @SOMA_2 := 0 ;
SET @SOMA_3 := 0 ;

SELECT 
pedidositens.PRODUTOS_ID, 
pedidositens.DESPRO, 
pedidositens.TIPUNI, 
SUM(pedidositens.VLRTOT) AS VALORTOTAL,
ROUND(SUM(pedidositens.VLRTOT) / (SELECT 
SUM(pedidositens.VLRTOT) 
FROM pedidositens
JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91) * 100, 2) AS PATICIPACAO,
(SELECT @PER_ACUMULADO := @PER_ACUMULADO + 
(ROUND(SUM(pedidositens.VLRTOT) / (SELECT 
SUM(pedidositens.VLRTOT) 
FROM pedidositens
JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91) * 100, 2) ) ) AS ACUMULADO,
CASE
	WHEN (SELECT @SOMA_1 := @SOMA_1 + 
		  	(ROUND(SUM(pedidositens.VLRTOT) / (SELECT 
			SUM(pedidositens.VLRTOT) 
			FROM pedidositens
			JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
			WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91) * 100, 2) ) )  > 50.00 THEN "C"
	WHEN (SELECT @SOMA_2 := @SOMA_2 + 
		  	(ROUND(SUM(pedidositens.VLRTOT) / (SELECT 
			SUM(pedidositens.VLRTOT) 
			FROM pedidositens
			JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
			WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91) * 100, 2) ) )  > 30.00 THEN "B"
	WHEN (SELECT @SOMA_3 := @SOMA_3 + 
		  	(ROUND(SUM(pedidositens.VLRTOT) / (SELECT 
			SUM(pedidositens.VLRTOT) 
			FROM pedidositens
			JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
			WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91) * 100, 2) ) )  < 31.00 THEN "A"
END AS CLASSIFICACAO

FROM pedidositens 
JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91
GROUP BY pedidositens.PRODUTOS_ID 
ORDER BY VALORTOTAL DESC
HARBOUR 3.2, HWGUI 2.23 B3, SEFAZCLASS, PDFClass, ADO + MariaDB/MySQL, RMChart
Fernando queiroz
Usuário Nível 4
Usuário Nível 4
Mensagens: 779
Registrado em: 13 Nov 2014 00:41
Localização: Porto Alegre/RS

query mysql para curva ABC

Mensagem por Fernando queiroz »

curva abc.jpg
HARBOUR 3.2, HWGUI 2.23 B3, SEFAZCLASS, PDFClass, ADO + MariaDB/MySQL, RMChart
Fernando queiroz
Usuário Nível 4
Usuário Nível 4
Mensagens: 779
Registrado em: 13 Nov 2014 00:41
Localização: Porto Alegre/RS

query mysql para curva ABC

Mensagem por Fernando queiroz »

Dei uma otimizada na query

Código: Selecionar todos

SET @TOT_VENDAS = (SELECT SUM(pedidositens.VLRTOT) 
                  FROM pedidositens 
						JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
						WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' 
						AND pedidos.ST = '0' 
						AND pedidos.TIPO_OPERACAO != 85 
						AND pedidos.TIPO_OPERACAO != 90 
						AND pedidos.TIPO_OPERACAO != 91);
SET @PER_ACUMULADO := 0 ;
SET @SOMA_1 := 0 ;
SET @SOMA_2 := 0 ;
SET @SOMA_3 := 0 ;
SELECT 
pedidositens.PRODUTOS_ID, 
pedidositens.DESPRO, 
pedidositens.TIPUNI, 
SUM(pedidositens.VLRTOT) AS VALORTOTAL,
ROUND(SUM(pedidositens.VLRTOT) / @TOT_VENDAS  * 100, 2) AS PARTICIPACAO,
(SELECT @PER_ACUMULADO := @PER_ACUMULADO + ROUND(SUM(pedidositens.VLRTOT) / @TOT_VENDAS  * 100, 2) ) AS ACUMULADO,
CASE
	WHEN (SELECT @SOMA_1 := @SOMA_1 + (ROUND(SUM(pedidositens.VLRTOT) / @TOT_VENDAS * 100, 2) ) )  > 50.00 THEN "C"
	WHEN (SELECT @SOMA_2 := @SOMA_2 + (ROUND(SUM(pedidositens.VLRTOT) / @TOT_VENDAS * 100, 2) ) )  > 30.00 THEN "B"
	WHEN (SELECT @SOMA_3 := @SOMA_3 + (ROUND(SUM(pedidositens.VLRTOT) / @TOT_VENDAS * 100, 2) ) )  < 31.00 THEN "A"
END AS CLASSIFICACAO
FROM pedidositens 
JOIN pedidos ON pedidositens.PEDIDOS_ID = pedidos.PEDIDOS_Id 
WHERE pedidos.DATVEN BETWEEN '2021-07-11' AND '2022-07-11' AND pedidos.ST = '0' AND pedidos.TIPO_OPERACAO != 85 AND pedidos.TIPO_OPERACAO != 90 AND pedidos.TIPO_OPERACAO != 91
GROUP BY pedidositens.PRODUTOS_ID 
ORDER BY VALORTOTAL DESC
HARBOUR 3.2, HWGUI 2.23 B3, SEFAZCLASS, PDFClass, ADO + MariaDB/MySQL, RMChart
Fernando queiroz
Usuário Nível 4
Usuário Nível 4
Mensagens: 779
Registrado em: 13 Nov 2014 00:41
Localização: Porto Alegre/RS

query mysql para curva ABC

Mensagem por Fernando queiroz »

TELA1.jpg
HARBOUR 3.2, HWGUI 2.23 B3, SEFAZCLASS, PDFClass, ADO + MariaDB/MySQL, RMChart
alexlucc
Usuário Nível 1
Usuário Nível 1
Mensagens: 49
Registrado em: 13 Nov 2016 19:19
Localização: Nova Iguaçu /rj

query mysql para curva ABC

Mensagem por alexlucc »

Bom dia Fernando, Quintas.

Obrigado pela ajuda amigos, consegui implementar ficou assim:



SELECT
d2.codbar,
d2.nomcom,
d2.nomcat,
d2.nomgru,
d2.nomlab,
d2.valor,
d2.vendidos,
d2.Faturamento,
d2.perc,
d2.Perc_Acumulado,
case when d2.Perc_Acumulado <= 80 then 'A'
when d2.Perc_Acumulado <= 95 then 'B'
ELSE 'C' END CLASSE

FROM (

SELECT
d1.codbar,
d1.nomcom,
d1.nomcat,
d1.nomgru,
d1.nomlab,
d1.valor,
d1.vendidos,
d1.Faturamento,
d1.perc,
SUM(d1.perc) OVER(order by d1.perc DESC) Perc_Acumulado
from(

SELECT
d.codbar,
d.nomcom,
d.nomcat,
d.nomgru,
d.nomlab,
d.valor,
d.vendidos,
sum(d.valor) over() as Faturamento,
cast(d.valor as decimal(15,2)) / cast(sum(d.valor) over() as decimal(15,3)) *100 perc

FROM (

SELECT i.codbar,p.nomcom,p.nomcat,p.nomgru,p.nomlab,SUM(i.subtot) as valor,SUM(i.qtde) as vendidos from itemvendas AS I
INNER JOIN PRODUTOS AS P ON ( P.codbar = I.codbar)
inner join vendas AS v ON (v.venda = i.venda)
WHERE v.dtemi BETWEEN '2022-01-01' AND '2022-06-30' AND v.cancelado = 0 AND v.tipoimpor <> 04
group BY i.codbar order BY valor desc) d)d1)d2


* A finalidade dessa é em relação a Venda, agora vou fazer uma com a finalidade de rotatividade do Estoque.
Responder