SQL Server存储过程插入重复行

时间:2018-05-25 15:49:33

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

我有一个列GetDup的表格,我希望根据此列的值重复记录。例如,如果GetDup中的值on为1,则复制一次记录。如果列中的值为2,则复制记录两次,依此类推,语句必须在循环语句中。

为此编写存储过程的好方法是什么?请帮忙。

输入:

+--------+--------------+---------------+
| Getdup | CustomerName | CustomerAdd   |
+--------+--------------+---------------+
|      1 | John         | 123 SomeWhere |
|      2 | Bob          | 987 SomeWhere |
+--------+--------------+---------------+

我想要的是什么:

+--------+--------------+---------------+
| Getdup | CustomerName | CustomerAdd   |
+--------+--------------+---------------+
|      1 | John         | 123 SomeWhere |
|      1 | John         | 123 SomeWhere |
|      2 | Bob          | 987 SomeWhere |
|      2 | Bob          | 987 SomeWhere |
|      2 | Bob          | 987 SomeWhere |
+--------+--------------+---------------+

picture of data

3 个答案:

答案 0 :(得分:2)

澄清后回答#2

抢救号码表!

我的示例中的数字表(或计数表,如果你想称之为),既是临时的又是非常小的。要使其更大,只需向z添加更多值并添加更多CROSS JOIN s。在我看来,数字表和日历表都应该包含在您拥有的每个数据库中。它们非常有用。

SQL Fiddle

MS SQL Server 2017架构设置

CREATE TABLE mytable ( Getdup int, CustomerName varchar(10), CustomerAdd varchar(20) ) ;

INSERT INTO mytable (Getdup, CustomerName, CustomerAdd)
VALUES (1,'John','123 SomeWhere'), (2,'Bob','987 SomeWhere')
;

查询1

;WITH z AS (
  SELECT * 
  FROM ( VALUES(0),(0),(0),(0) ) v(x)
)
, numTable AS (
  SELECT num 
  FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY z1.x)-1 num 
    FROM z z1 
    CROSS JOIN z z2 
  ) s1
)
SELECT t1.Getdup, t1.CustomerName, t1.CustomerAdd
FROM mytable t1
INNER JOIN numTable ON t1.getdup >= numTable.num
ORDER BY CustomerName, CustomerAdd

<强> Results

| Getdup | CustomerName |   CustomerAdd |
|--------|--------------|---------------|
|      2 |          Bob | 987 SomeWhere |
|      2 |          Bob | 987 SomeWhere |
|      2 |          Bob | 987 SomeWhere |
|      1 |         John | 123 SomeWhere |
|      1 |         John | 123 SomeWhere |

<强> -------------------------------------------- ------------------------------

原始回答

编辑:在进一步澄清问题后,这不会重复行,这只会复制一列中的数据。

像其中一个可能有用。

<强> T-SQL

SELECT replicate(mycolumn,getdup) AS x
FROM mytable

<强>的MySQL

SELECT repeat(mycolumn,getdup) AS x
FROM mytable

Oracle SQL

SELECT rpad(mycolumn,getdup*length(mycolumn),mycolumn) AS x
FROM mytable

<强>的PostgreSQL

SELECT repeat(mycolumn,getdup+1) AS x
FROM mytable

如果您可以提供更多详细信息,以确切了解您的需求以及您正在使用的内容,我们可以为您提供更好的帮助。

注2:根据您的需要,您可能需要做一些数学魔术。如果GetDup为1则说明您需要一个副本。如果这意味着您的输出应为GetDup``GetDup,那么您需要在repeat()replicate()rpad()函数中添加一个。即replicate(mycolumn,getdup+1)。 Oracle SQL会有所不同,因为它使用rpad()

答案 1 :(得分:0)

在标准SQL中,您可以使用递归CTE:

with recursive cte as (
      select t.dup, . . .
      from t
      union all
      select cte.dup - 1, . . .
      from cte
      where cte.dup > 1
     )
select *
from cte;

当然,并非所有数据库都支持递归CTE(并且其中某些关键字未使用recursive关键字)。

答案 2 :(得分:0)

所以,你想要递归解决方案:

with t as (
    select Getdup, CustomerName, CustomerAdd, 0 as id
    from table
    union all
    select Getdup, CustomerName, CustomerAdd, id + 1
    from t
    where id < getdup
)
insert into table (col1, col2, col3)
select Getdup, CustomerName, CustomerAdd
from t
order by getdup
option (maxrecursion 0);