SSMS
 sql >> Database >  >> Database Tools >> SSMS

Dividi il set in intervalli percentuali irregolari

Non so, se ho capito bene...

Prima di tutto sembra esserci un errore piuttosto evidente qui:

    WHEN t.bucket > 60 AND t.bucket <=90 THEN 'NULL'

Non dovrebbe essere questo:

    WHEN t.bucket >90 THEN 'NULL'

La funzione NTILE distribuirà i tuoi set in secchi piuttosto uniformi. Controlla il mio output e scopri come si comporta nei casi d'angolo. Suggerisco di utilizzare una percentuale calcolata per riga come qui:

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;

--Uso questo #tmpBuckets-table per avvicinarmi al tuo Ho un tavolo scenario

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;

Penso che tu sappia come usare un tale cte per aggiornare la tabella dei sorgenti. Altrimenti torna con un'altra domanda :-)