SSMS
 sql >> Base de Dados >  >> Database Tools >> SSMS

Dividir o conjunto em intervalos de porcentagem desiguais


Não sei, se entendi direito...

Em primeiro lugar, parece haver um erro bastante óbvio aqui:
    WHEN t.bucket > 60 AND t.bucket <=90 THEN 'NULL'

Não deveria ser isso:
    WHEN t.bucket >90 THEN 'NULL'

A função NTILE irá espalhar seus conjuntos em baldes bastante uniformes. Verifique minha saída e descubra como isso se comporta nos casos de canto. Sugiro usar uma porcentagem calculada por linha como aqui:
WITH tally
(vals, bucket)
AS
(
    SELECT
         DATEADD(DAY, - ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), GETDATE())
        ,NTILE(100) OVER (ORDER BY (SELECT NULL))
    FROM
    (
        VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0)) AS a(n)
        CROSS JOIN (VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0)) AS b(n)
        CROSS JOIN (VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0)) AS c(n)
    )
SELECT *
INTO #tmpBuckets
FROM Tally;

--Eu uso esta #tmpBuckets-table para chegar mais perto da sua Eu tenho uma mesa cenário
WITH Numbered AS
(
    SELECT *
          ,ROW_NUMBER() OVER(ORDER BY vals DESC) / ((SELECT COUNT(*) FROM #tmpBuckets)/100.0)  AS RunningPercentage
    FROM #tmpBuckets
)
,ComputeBuckets AS
(
    SELECT
     t.*
    , CASE
        WHEN t.RunningPercentage <= 35 THEN 'a'
        WHEN t.RunningPercentage > 35 AND t.RunningPercentage <=60 THEN 'b'
        WHEN t.RunningPercentage > 60 AND t.RunningPercentage <=90 THEN 'c'
        WHEN t.RunningPercentage >90  THEN 'NULL'
    END AS ShnugoMethod
    , CASE
        WHEN t.bucket <= 35 THEN 'a'
        WHEN t.bucket > 35 AND t.RunningPercentage <=60 THEN 'b'
        WHEN t.bucket > 60 AND t.RunningPercentage <=90 THEN 'c'
        WHEN t.bucket > 90  THEN 'NULL'
    END AS ZikatoMethod
    FROM Numbered t
)
SELECT cb.*
FROM ComputeBuckets cb
ORDER BY cb.vals DESC

GO
DROP TABLE #tmpBuckets;

Eu acho que você sabe, como usar tal cte para atualizar a tabela de origem. Caso contrário, volte com outra pergunta :-)