【发布时间】:2019-03-20 18:05:09
【问题描述】:
每天我都会返回一组 x 行(5 到 2000 之间)。
我需要根据规则更新此集合中的一列。我认为这个(不完全有效)示例说明了这一点
/*
35% a
25% b
30% c
10% null
*/
WITH tally
(vals, updateThis, bucket)
AS
(
SELECT
DATEADD(DAY, - ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), GETDATE())
, NULL
, 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)
)
--UPDATE
--SET updateThis
, updated
AS
(
SELECT
t.vals
, CASE
WHEN t.bucket <= 35 THEN 'a'
WHEN t.bucket > 35 AND t.bucket <=60 THEN 'b'
WHEN t.bucket > 60 AND t.bucket <=90 THEN 'c'
WHEN t.bucket > 60 AND t.bucket <=90 THEN 'NULL'
END AS updated
, t.bucket
FROM tally t
)
SELECT
U.updated
, COUNT(1) AS actual
FROM
updated u
GROUP BY U.updated
此解决方案并不精确,即使 a + b + c 确实构成 100%,它也可能不会更新所有行。此外,它不适用于小于 100 行的集合。
我目前的工作解决方案是:
- 计算总行数
- 计算实际需要的行数
(CEILING((@totalRows * ratio) / 100) - 在 WHILE LOOP 中更新最终集,选择当前值和所需的行。
有没有更好的基于集合的解决方案可以帮助我摆脱循环?
【问题讨论】:
标签: tsql set ssms sql-server-2016