突破一行到多行与SQL的最大列值

问题描述 投票:0回答:3

[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]。

tsql group-by count grouping
3个回答
0
投票

我想我想通了:

    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

0
投票

不使用循环版本

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;

0
投票

你也可以使用一个递归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
© www.soinside.com 2019 - 2024. All rights reserved.