[A]柱可以是任何值,但是如果它超过55,它需要被细分,使得没有行都有一个柱[A]的值超过55,并且使得没有值的丢失。
一个人怎么会在完成SQL这一目标?
摸索了一段时间,我尝试不同的事情后,我迷路了。我主要是C#开发人员,从来没有试过这样做逻辑电平的SQL。
select '01' as id, 65 as cnt into #temptbl
insert into #temptbl values
('02',100),
('03',200),
('04',45)
insert into #temptbl
select id, cnt - 55 from #temptbl where cnt > 55
update #temptbl set cnt = 55 where cnt > 55
select * from #temptbl order by id
select id, sum(cnt) as newCnt from #temptbl group by id
drop table #temptbl
比方说,我有一个行,其中列[A]的值为200列的[A]应该是55.我需要此行拆分为4行的最大值。 3行将具有柱值在55 [A]和最后一行将具有柱价值35 [A]。
我想我想通了:
select '01' as id, 65 as cnt into #temptbl
insert into #temptbl values
('02',100),
('03',200),
('04',45)
declare @temptbl2 TABLE (id varchar(2), cnt bigint)
while Exists(select 1 from #temptbl where cnt > 55)
BEGIN
insert into @temptbl2 select id, 55 as cnt from #temptbl where cnt > 55
update #temptbl set cnt = cnt - 55 where cnt > 55
insert into #temptbl select * from @temptbl2
delete from @temptbl2
END
select * from #temptbl order by id
select id, sum(cnt) as newCnt from #temptbl group by id
drop table #temptbl
不使用循环版本
DECLARE @limit INT = 55;
SELECT '01' AS id, 65 AS cnt INTO #temptbl;
INSERT INTO #temptbl VALUES ('02', 100), ('03', 200), ('04', 45);
INSERT INTO #temptbl
SELECT dupl.id
, dupl.cnt
FROM #temptbl AS t
CROSS APPLY ( SELECT id
, @limit AS cnt
FROM ( SELECT ROW_NUMBER() OVER (ORDER BY S.object_id) AS row_num
FROM sys.all_objects AS S) AS a
WHERE a.row_num <= (t.cnt - 1) / @limit) AS dupl
WHERE t.cnt > @limit;
UPDATE #temptbl SET cnt = cnt % @limit WHERE cnt > @limit;
SELECT * FROM #temptbl ORDER BY 1, 2;
DROP TABLE #temptbl;
你也可以使用一个递归CTE这一点。
该示例使用演示表变量。
declare @VarTable table (code varchar(2) primary key, cnt int);
insert into @VarTable (code, cnt) values
('01', 65),
('02',100),
('03',200),
('04', 45);
declare @Limit int = 55;
WITH RecursiveCTE AS
(
SELECT code, IIF(cnt > @Limit, @Limit, cnt) AS cnt, (cnt - @Limit) AS Remaining
FROM @VarTable
UNION ALL
SELECT code, IIF(Remaining > @Limit, @Limit, Remaining), (Remaining - @Limit)
FROM RecursiveCTE
WHERE Remaining > 0
)
SELECT code AS id, cnt
FROM RecursiveCTE
ORDER BY id, cnt DESC;
结果:
id cnt
-- ---
01 55
01 10
02 55
02 45
03 55
03 55
03 55
03 35
04 45