如果超过值(Y)而不使用光标,是否可以将值(X)分割几个月?
例如,我有X = 505的值,我希望尽可能多地将其拆分,每个月的最大值为100(值Y = 100)?
所以我的预期输出是:
JAN 100
FEB 100
MAR 100
APR 100
MAY 100
JUN 5
我并不关心重叠(6月5日),如果没有这个可能就可以了。
答案 0 :(得分:1)
您可以使用数字表格使用CROSS APPLY在一个月的序列中传播值,如下所示。
create table T(
id int,
dat datetime,
val int,
primary key(id, dat)
);
insert into T values (1, '20140101', 100);
insert into T values (2, '20140101', 99);
insert into T values (3, '20140201', 274);
insert into T values (4, '20140301', 300);
declare @chunk int = 100;
select
id,
dateadd(month,n-1,dat) as dat,
case when n=max(n) over (partition by id) then (val-1)%@chunk+1 else @chunk end as val
from T
cross apply (
select n from Nums
where n <= ceiling((val+@chunk-1)/@chunk)
) as N(n);
结果:
id dat val
1 2014-01-01 100
2 2014-01-01 99
3 2014-02-01 100
3 2014-03-01 100
3 2014-04-01 74
4 2014-03-01 100
4 2014-04-01 100
4 2014-05-01 100
(如果你的值不是整数,你需要稍微调整一下。)
如果您没有方便的话,这里有一些SQL可以创建一个从1到1024的数字表。
create table Nums(
n int primary key
)
insert into Nums values (1);
declare @i int = 10;
while @i>0 begin
insert into Nums
select max(n) over () + n
from Nums;
set @i -= 1;
end;
答案 1 :(得分:0)
你能使用TOP X(行)语法吗?如果要构建SQL查询字符串,可以使用:
选择 TOP(505/100) * 从表
这样505/100轮到一个整数,你只得到5行。
然后你需要加入一个Calendar表来获取月份
答案 2 :(得分:0)
一点点数学可以帮助,数学 使用Steve Kass答案中的表格
declare @chunk int = 100;
WITH Base(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1
), Base10(N) AS (
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) - 1
FROM Base
), Counter(N) AS (
SELECT u.N + 10*t.N
FROM Base10 u
CROSS JOIN Base10 t
)
SELECT id
, DateAdd(MONTH, N, dat) Month
, Cast((val - (@chunk * N)) / @chunk as BIT) * @chunk
+ (1 - Cast((val - (@chunk * N)) / @chunk as BIT)) * (val % @chunk) Value
FROM T
LEFT JOIN Counter ON N < CEILING(Cast(val as Float) / @chunk)
CTE只是为了获得一个计数器,位转换用作IF,可以转换为
IF (val - (100 * N) / 100) > 0 THEN
RETURN 100
ELSE
RETURN VAL % 100
END IF
val列被转换为Float以防止整数除法,我使用LEFT JOIN
而不是CROSS JOIN
来在那里添加条件而不是WHERE
条件< / p>
SQLFiddle演示,在演示中,块是静态的