0

我有两列

在此处输入图像描述

我想输出查询

在此处输入图像描述

我尝试在 SQL 中使用循环,但我未能输出查询

我的问题是:如何通过 [Total] 列中的数字重复 [Name] 列中的值?

4

3 回答 3

3

This is usually handled with a recursive subquery. I derived a row order in case of duplicate names, however, that is best served using a unique key.

SQL Fiddle

MS SQL Server 2017 Schema Setup:

CREATE TABLE Names(name NVARCHAR(50), total INT)
INSERT Names VALUES('ahmed',3),('mahmoud',2),('ahmed',5)

Query 1:

;WITH Normalized AS
(
    SELECT *, RowNumber = ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM Names
)
,ReplicateAmount AS
 (
    SELECT  name, running_total=total, total, RowNumber
    FROM Normalized

    UNION ALL

    SELECT R.name, running_total=(R.running_total - 1), R.total , R.RowNumber
    FROM ReplicateAmount R INNER JOIN Normalized N ON R.RowNumber = N.RowNumber
    WHERE R.running_total > 1
)   

SELECT 
    name,instance=RowNumber,total=1,OriginalTotal=total,running_total 
FROM 
    ReplicateAmount
ORDER BY
    RowNumber,name,total,running_total
OPTION (MAXRECURSION 0)     

Results:

|    name | instance | total | OriginalTotal | running_total |
|---------|----------|-------|---------------|---------------|
|   ahmed |        1 |     1 |             3 |             1 |
|   ahmed |        1 |     1 |             3 |             2 |
|   ahmed |        1 |     1 |             3 |             3 |
| mahmoud |        2 |     1 |             2 |             1 |
| mahmoud |        2 |     1 |             2 |             2 |
|   ahmed |        3 |     1 |             5 |             1 |
|   ahmed |        3 |     1 |             5 |             2 |
|   ahmed |        3 |     1 |             5 |             3 |
|   ahmed |        3 |     1 |             5 |             4 |
|   ahmed |        3 |     1 |             5 |             5 |
于 2019-12-30T20:17:32.887 回答
3

您可以比接受的答案简单得多。

我建议创建一个带有连续正整数的数字表...

CREATE TABLE dbo.Numbers(Number INT PRIMARY KEY);

INSERT INTO dbo.Numbers
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM sys.all_objects o1, 
     sys.all_objects o2

然后加入number <= total(如下)

SELECT name, 1 AS total
FROM Names nam 
JOIN dbo.Numbers num ON num.Number <= nam.total;

如果您在 2017 年以上,另一种“有趣”的方法如下(SQL Fiddle

SELECT name, 1 AS total
FROM Names
CROSS APPLY STRING_SPLIT(SPACE(total - 1), ' ')
于 2019-12-30T20:38:57.780 回答
0

对于您的封闭式问题;

CREATE TABLE #Test1(
    [ID] [int] NULL,
    [Cnt] [varchar](50) NULL
) ON [PRIMARY]
GO


CREATE TABLE #Test2(
    [ID] [int] NULL,
    [col1] [varchar](50) NULL,
    [col2] [varchar](50) NULL,
    [col3] [varchar](50) NULL
) ON [PRIMARY]
GO

CREATE TABLE #Test3(
    [ID1] [int] NULL,
    Cnt int,
    Id2 int,
    [col1] [varchar](50) NULL,
    [col2] [varchar](50) NULL,
    [col3] [varchar](50) NULL
) ON [PRIMARY]
GO


INSERT INTO #TEST1 (ID, Cnt) VALUES (1, 2)
INSERT INTO #TEST1 (ID, Cnt) VALUES (2, 3)
INSERT INTO #TEST1 (ID, Cnt) VALUES (3, 1)
INSERT INTO #TEST1 (ID, Cnt) VALUES (4, 2)
INSERT INTO #TEST1 (ID, Cnt) VALUES (5, 1)
INSERT INTO #TEST1 (ID, Cnt) VALUES (6, 4)


INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (1, 'a1', 'b1', 'c1')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (2, 'a2', 'b2', 'c2')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (3, 'a3', 'b3', 'c3')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (4, 'a4', 'b4', 'c4')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (5, 'a5', 'b5', 'c5')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (6, 'a6', 'b6', 'c6')

declare @a int = 1, @b int, @c int = 0;
while @a <= (select MAX(Id) from #Test1)
begin
    set @b = (select Cnt from #Test1 where ID = @a);
    set @c = 0;
    while @c < @b begin
        insert into #Test3 (ID1, Cnt, Id2, col1, col2, col3) select @a, @b, @a, col1, col2, col3 from #Test2 where ID = @a;

        set @c += 1;
    end
    
    SET @a += 1;
end

select * from #Test3 order by 1, 2;

在此处输入图像描述

于 2021-04-23T02:43:34.873 回答