通过计算单元格数据将单行数据转换为多行

时间:2016-10-12 10:39:55

标签: sql sql-server sql-server-2008

create table #tmp (Name varchar(10), Code varchar(10), Date datetime, Total int)
insert into #tmp
select 'abc','A-8','2016-10-12',45

现在我想要基于Total的分割数据。

例如,如果我需要将数据拆分20,那么结果应该看起来像

Name    Code    Date        Total
abc     A-8     2016-10-12  20
abc     A-8     2016-10-12  20
abc     A-8     2016-10-12  5 

你可以看到上面的代码,你可以看到我将我的单行拆分为3行,所有数据都是相同的,除了Total。

总计应该以不同的方式计算,因为结果我有3行。如果总数为65,那么将有4行具有相同的数据,只有总数将被更改,如20,20,20,5,并且剩余将是相同的。

我不想像WHILE等那样使用任何循环。

2 个答案:

答案 0 :(得分:1)

假设你有一个像dbo.Nums这样的表

SELECT *
FROM dbo.Nums

n
-----------
1
2
3
4
5
...
10000000

或者您可以将以下查询用于相同目的。

SELECT ROW_NUMBER() OVER (ORDER BY object_id) FROM sys.all_objects

然后查询

DECLARE @d AS INT = 20;

SELECT #tmp.Name, Code, Date, @d AS Total
FROM #tmp
CROSS JOIN dbo.Nums
WHERE dbo.Nums.n <= (#tmp.Total / @d)
UNION ALL
SELECT #tmp.Name, Code, Date, (Total % @d) AS Total
FROM #tmp
WHERE (Total % @d) <> 0

答案 1 :(得分:0)

您需要使用计数表。 Tally表应根据您的要求记录从1到5或1到100.我创建了tmp计数表,但您可以为它创建实际的计数表,如下所示:

create table #tmp (Name varchar(10), Code varchar(10), Date datetime, Total int)
create table #tmp_tally (sno int)

insert into #tmp_tally
select 1
union all
select 2
union all
select 3
union all
select 4
union all
select 5

insert into #tmp
select 'abc','A-8','2016-10-12',45;

select #tmp.*, sno,case when ceiling(total/20) >= sno  then 20 else total % 20 end
from #tmp,#tmp_tally
where ceiling(total/20) >= sno- case when (total % 20) = 0 then 0 else 1 end