我必须根据一个计数列将一行分为多行。如果count为6,则行应拆分为2,第一行的计数为5,下一行为1。如果count为17,将进行4拆分,每3列的行数为5,最后一行为2。
表将包含2列:
id CNT
------------
10 17
上一行应分成4个,如下所示:
id CNT
--------------------
10 5
10 5
10 5
10 2
我尝试使用mod和除法来查找拆分总数,但是找不到最终解决方案。
请提供您的意见以实现这一目标。
答案 0 :(得分:2)
您可以尝试一下。我不确定teradata
中使用的语法,但这肯定会使您了解如何解决问题。
首先,我们需要找到每个数字相对于id的商和余数部分。然后商就是您要重复循环的次数,为此我们使用recursive cte
,余数是最后一行,需要添加最后一行以获得等于您的值的数字总和。
示例查询将是这样。
declare @tab table ( id int, num int )
insert into @tab ( id, num )
values ( 1, 17 )
, ( 2, 22 )
; with cte as (
select id, num , num %5 as remainder, num/5 as quo from @tab )
, ct (sl, id, num, val) as (
select 1 as sl, id, num, 5 as val from cte
union all
select c.sl+1, t.id, t.num, c.val from cte as t inner join ct as c on t.id=c.id where c.sl<t.quo
)
, cfinal (id, num, val) as (
select id, num, val from ct
union all
select id, num, remainder from cte
)
select * from cfinal order by id, val desc
结果
id num val
----------- ----------- -----------
1 17 5
1 17 5
1 17 5
1 17 2
2 22 5
2 22 5
2 22 5
2 22 5
2 22 2
答案 1 :(得分:1)
DarkRob的递归查询可以简化为
WITH RECURSIVE cte AS
(
SELECT id
-- remainder or 5 if no remainder
,CASE WHEN Cnt MOD 5 = 0 THEN 5 ELSE Cnt MOD 5 END AS val
-- how many rows left?
,(Cnt - val) / 5 AS x
FROM tab
WHERE Cnt > 0
UNION ALL
SELECT id, 5, x - 1
FROM cte
WHERE x > 0
)
SELECT *
FROM cte
但是我更愿意(ab)使用Teradata的时间序列扩展功能:
SELECT tab.*,
End(pd) - Begin(pd) AS val
FROM tab
WHERE Cnt > 0
-- create one rows for each group of 5 (days)
EXPAND ON PERIOD(DATE, DATE + Cnt) AS pd BY INTERVAL '5' DAY