Хранимая процедура SQL Server, вставляющая повторяющиеся строки - PullRequest
0 голосов
/ 25 мая 2018

У меня есть таблица со столбцом GetDup, и я хотел бы получить дубликаты записей на основе значения этого столбца.Например, если значение в 1 в GetDup, дублируйте запись один раз.Если значение в столбце равно 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 |
+--------+--------------+---------------+

изображение данных

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Ответ № 2 после уточнения

Таблица чисел для спасения!

Таблица чисел в моем примере (или таблица подсчета, если вы хотите так ее назвать), является как временной, так и очень маленькой.Чтобы увеличить его, просто добавьте больше значений к z и добавьте больше CROSS JOIN с.На мой взгляд, таблица чисел и таблица календаря - это то, что должно быть в каждой вашей базе данных.Они чрезвычайно полезны.

Скрипка SQL

Настройка схемы 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

Результаты :

| 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().

0 голосов
/ 25 мая 2018

Итак, вы хотите рекурсивное решение:

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); 
0 голосов
/ 25 мая 2018

В стандартном 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 не используется в некоторых из них).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...