Tengo una tabla que incluye una columna de valores decimales, como este:
id value size
-- ----- ----
1 100 .02
2 99 .38
3 98 .13
4 97 .35
5 96 .15
6 95 .57
7 94 .25
8 93 .15
Lo que necesito lograr es un poco difícil de describir, así que tengan paciencia conmigo. Lo que intento hacer es crear un valor agregado de la sizecolumna que se incremente en 1 cada vez que las filas anteriores sumen 1, cuando están en orden descendente de acuerdo con value. El resultado se vería así:
id value size bucket
-- ----- ---- ------
1 100 .02 1
2 99 .38 1
3 98 .13 1
4 97 .35 1
5 96 .15 2
6 95 .57 2
7 94 .25 2
8 93 .15 3
Mi primer intento ingenuo fue mantener un funcionamiento SUMy luego CEILINGese valor, sin embargo, no maneja el caso donde algunos registros sizeterminan contribuyendo al total de dos cubos separados. El siguiente ejemplo podría aclarar esto:
id value size crude_sum crude_bucket distinct_sum bucket
-- ----- ---- --------- ------------ ------------ ------
1 100 .02 .02 1 .02 1
2 99 .38 .40 1 .40 1
3 98 .13 .53 1 .53 1
4 97 .35 .88 1 .88 1
5 96 .15 1.03 2 .15 2
6 95 .57 1.60 2 .72 2
7 94 .25 1.85 2 .97 2
8 93 .15 2.00 2 .15 3
Como puede ver, si simplemente usara CEILINGen el crude_sumregistro # 8 se asignaría al depósito 2. Esto se debe a que los sizeregistros # 5 y # 8 se dividen en dos depósitos. En cambio, la solución ideal es restablecer la suma cada vez que llega a 1, que luego incrementa la bucketcolumna y comienza una nueva SUMoperación que comienza en el sizevalor del registro actual. Debido a que el orden de los registros es importante para esta operación, he incluido la valuecolumna, que debe ordenarse en orden descendente.
Mis intentos iniciales han implicado hacer múltiples pases sobre los datos, una vez para realizar la SUMoperación, una vez más para CEILINGeso, etc. Aquí hay un ejemplo de lo que hice para crear la crude_sumcolumna:
SELECT
id,
value,
size,
(SELECT TOP 1 SUM(size) FROM table t2 WHERE t2.value<=t1.value) as crude_sum
FROM
table t1
Que se utilizó en una UPDATEoperación para insertar el valor en una tabla para trabajar más tarde.
Editar: me gustaría dar otra puñalada para explicar esto, así que aquí va. Imagine que cada registro es un elemento físico. Ese artículo tiene un valor asociado y un tamaño físico menor que uno. Tengo una serie de cubos con una capacidad de volumen de exactamente 1, y necesito determinar cuántos de estos cubos necesitaré y en qué cubo entra cada artículo de acuerdo con el valor del artículo, ordenados de mayor a menor.
Un elemento físico no puede existir en dos lugares a la vez, por lo que debe estar en un cubo u otro. Es por eso que no puedo hacer una CEILINGsolución total + , porque eso permitiría que los registros contribuyan con su tamaño a dos cubos.
distinct_countcomplica las cosas. Aaron Bertrand tiene un excelente resumen de sus opciones en SQL Server para este tipo de trabajo de ventanas. He utilizado el método de "actualización peculiar" para calcular distinct_sum, que puedes ver aquí en SQL Fiddle , pero esto no es confiable.