none
Classificação ABC da Query RRS feed

  • Pergunta

  • Gostaria de uma ajuda para criar uma coluna com a classificação ABC da coluna acumulado.
    Essa é a Query:

    DECLARE 
    @TOTAL DECIMAL(8,2)
    SET 
    @TOTAL=(SELECT SUM(C6_VALOR)
    FROM 
    SC6010
    WHERE
    C6_TES IN('501','502','503','504','505','506','507','508','509','520') 
    --AND C6_ENTREG BETWEEN GETDATE()-2 AND GETDATE ()-1 
    AND SC6010.D_E_L_E_T_ <> '*')


    ;WITH CTE_DADOS AS (
    SELECT

    C6_PRODUTO AS COD_PRODUTO,
    C6_CLI AS CLIENTE,
    A1_NOME AS NOME,
    C6_DESCRI AS DESCRICAO, 
    SUM(C6_QTDVEN)AS QUANTIDADE,
    SUM(C6_VALOR) AS VALOR_TOTAL, 
    (ROUND(SUM(C6_VALOR)*100/@TOTAL,2)) AS PERCENTUAL



    FROM
    SC6010
    INNER JOIN SA1010 A1 ON A1_COD=C6_CLI
    WHERE
    C6_TES IN('501','502','503','504','505','506','507','508','509','520') 
    --AND C6_ENTREG BETWEEN GETDATE()-2 AND GETDATE ()-1 
    AND SC6010.D_E_L_E_T_ <> '*'

    GROUP BY 
    C6_PRODUTO,C6_DESCRI,C6_CLI,A1_NOME

    ), CTE_DADOS2 AS (SELECT ROW_NUMBER() OVER(ORDER BY PERCENTUAL DESC) AS NUMERADOR, COD_PRODUTO, CLIENTE, NOME, DESCRICAO, QUANTIDADE, VALOR_TOTAL, PERCENTUAL
     FROM CTE_DADOS)


    SELECT *,
     ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
    FROM CTE_DADOS2 A

    GROUP BY NUMERADOR, COD_PRODUTO, CLIENTE, NOME, DESCRICAO, QUANTIDADE, VALOR_TOTAL, PERCENTUAL
    ORDER BY 
    ACUMULADO

    Ela já retorna os todos os valores necessário mas não estou conseguindo gerar a coluna com a classificação ABC

    Quem puder ajudar...

    Obrigado!

    sexta-feira, 25 de maio de 2018 18:08

Respostas

  • Boa noite,

    Experimente alterar o trecho final que segue abaixo:

    SELECT *,
     ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
    FROM CTE_DADOS2 A
    
    GROUP BY NUMERADOR, COD_PRODUTO, CLIENTE, NOME, DESCRICAO, QUANTIDADE, VALOR_TOTAL, PERCENTUAL
    ORDER BY 
    ACUMULADO

    para algo mais ou menos dessa forma:

    , CTE_DADOS3 AS
    (
        SELECT 
            *,
            ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
        FROM CTE_DADOS2 A
    )
    
    SELECT
        *,
        CASE 
            WHEN ACUMULADO <= 65 THEN 'A'
            WHEN ACUMULADO <= 90 THEN 'B'
            ELSE 'C'
        END AS CLASSIFICACAO
    FROM CTE_DADOS3
    ORDER BY 
        ACUMULADO

    Essa versão deve funcionar com as 2 versões do SQL Server que você utiliza.

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 28 de maio de 2018 23:38

Todas as Respostas

  • Boa tarde,

    Qual versão do SQL Server você está utilizando?

    Se for até a versão 2008 acho que uma alternativa seria utilizar mais uma CTE para no final verificar o valor da coluna Acumulado com um Case e gerar a classificação ABC.

    Se for uma versão mais recente é provável que seja possível mudar um pouco a query utilizando Over Aggregate.


    Assinatura: http://www.imoveisemexposicao.com.br

    sexta-feira, 25 de maio de 2018 19:27
  • Boa tarde, 

    Possuo acesso a versão 2008 e a 2014 depende de onde estou, mas resolvendo na de 2008 pode me dar uma luz para outra.

    segunda-feira, 28 de maio de 2018 18:21
  • Boa noite,

    Experimente alterar o trecho final que segue abaixo:

    SELECT *,
     ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
    FROM CTE_DADOS2 A
    
    GROUP BY NUMERADOR, COD_PRODUTO, CLIENTE, NOME, DESCRICAO, QUANTIDADE, VALOR_TOTAL, PERCENTUAL
    ORDER BY 
    ACUMULADO

    para algo mais ou menos dessa forma:

    , CTE_DADOS3 AS
    (
        SELECT 
            *,
            ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
        FROM CTE_DADOS2 A
    )
    
    SELECT
        *,
        CASE 
            WHEN ACUMULADO <= 65 THEN 'A'
            WHEN ACUMULADO <= 90 THEN 'B'
            ELSE 'C'
        END AS CLASSIFICACAO
    FROM CTE_DADOS3
    ORDER BY 
        ACUMULADO

    Essa versão deve funcionar com as 2 versões do SQL Server que você utiliza.

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 28 de maio de 2018 23:38
  • Boa noite,

    Experimente alterar o trecho final que segue abaixo:

    SELECT *,
     ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
    FROM CTE_DADOS2 A
    
    GROUP BY NUMERADOR, COD_PRODUTO, CLIENTE, NOME, DESCRICAO, QUANTIDADE, VALOR_TOTAL, PERCENTUAL
    ORDER BY 
    ACUMULADO

    para algo mais ou menos dessa forma:

    , CTE_DADOS3 AS
    (
        SELECT 
            *,
            ROUND(ISNULL((SELECT A.PERCENTUAL + SUM(B.PERCENTUAL) FROM CTE_DADOS2 B WHERE NUMERADOR <= A.NUMERADOR-1),A.PERCENTUAL),2) AS ACUMULADO
        FROM CTE_DADOS2 A
    )
    
    SELECT
        *,
        CASE 
            WHEN ACUMULADO <= 65 THEN 'A'
            WHEN ACUMULADO <= 90 THEN 'B'
            ELSE 'C'
        END AS CLASSIFICACAO
    FROM CTE_DADOS3
    ORDER BY 
        ACUMULADO

    Essa versão deve funcionar com as 2 versões do SQL Server que você utiliza.

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    Funcionou meu amigo, muito obrigado!
    segunda-feira, 4 de junho de 2018 16:58