想了解如何根据总值/计数创建序列号字段吗?
有没有任何可能的方法可以在不使用while循环的情况下生成结果?谢谢
CustID | EmpID | TotalCount |
---|---|---|
40 | 1001 | 3|
50 | 1002 | 5 |
解决此类问题的一种常见方法是使用Numbers
表——一个只将数字从1递增到任意极限的表。这个表非常有用,所以在每个数据库中都有一个表是个好主意。从链接文章复制:
DECLARE @UpperBound INT = 1000000;
;WITH cteN(Number) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id]) - 1
FROM sys.all_columns AS s1
CROSS JOIN sys.all_columns AS s2
)
SELECT [Number] INTO dbo.Numbers
FROM cteN WHERE [Number] <= @UpperBound;
CREATE UNIQUE CLUSTERED INDEX CIX_Number ON dbo.Numbers([Number]);
如果您有这样一个表,生成重复行可以使用CROSS JOIN:来完成
SELECT MyTable.*
FROM MyTable CROSS join Numbers
WHERE TotalCount < Numbers.Number
要添加序列号,可以使用ROW_number((OVER((。要为每个CustID获得不同的起点,可以将MIN((与OVER子句一起使用。聚合函数可以与限制其应用范围的OVER
关闭一起使用:
SELECT
MIN(CustID) OVER (PARTITION BY CustID)
+ ROW_NUMBER() OVER(ORDER BY CustId,Number)
AS SeqNo,
MyTable.*
FROM MyTable CROSS join Numbers
WHERE TotalCount < Numbers.Number
在我看来,最简单的方法是使用"numbers"表并将它们交叉连接以创建适当数量的行。
一个简单的数字表是
CREATE TABLE #n (n int PRIMARY KEY);
INSERT INTO #n (n) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
数字表的一种更好的方法(实际上,与这个答案类似的总体方法(可以在"如何将列数据透视到不能超过最大数量总和的行中?"中找到?
现在,进行交叉连接从根本上说会在两个表之间"相乘"。主要是将数字表中的数字限制为TotalCount。
SELECT MyTable.CustID + n.n AS SeqNum, MyTable.CustID, MyTable.EmpID, MyTable.TotalCount
FROM MyTable
CROSS JOIN #n AS n
WHERE n.n < TotalCount
您也可以使用内部联接来执行此操作,并将where子句移动为联接本身的一部分。
SELECT MyTable.CustID + n.n AS SeqNum, MyTable.CustID, MyTable.EmpID, MyTable.TotalCount
FROM MyTable
INNER JOIN #n AS n ON n.n < TotalCount
编辑:请注意,SeqNum在上面并不一定是唯一的——类似于@Luuk关于TotalCount超过10时会发生什么的评论/问题。还增加了INNER JOIN版本。
@seanb@pana
对于总计数,我将从我的表中获得最小和最大客户ID
CREATE TABLE #n (n int);
declare @start int, @end int
select @start= min(rk) from MyTable
select @end= max(rk) from MyTable
while @start <=@end
begin
INSERT INTO #n (n) VALUES (@start)
set @start=@start+1
end
我只需要使用递归CTE:
with cte as (
select CustID, EmpID, TotalCount, 1 as n
from t
union all
select CustID, EmpID, TotalCount, n + 1
from cte
where n < TotalCount
)
select (CustId + n - 1) as seqno, CustID, EmpID, TotalCount
from cte;
如果需要添加100多行,则需要option (maxrecursion 0)
作为查询中的最后一行。