Есть ли способ дублировать строку?

Я хочу что-то, что работает противоположно COUNT, это как обратное GROUP BYSPLIT BY?) но что вы можете работать более свободно.

До сих пор я видел, что все "команды" предназначены для ограничений или спецификации, что означает, что вы не можете создать таблицу / набор большего размера, чем та, которая у вас уже есть. Я говорю о создании некой динамической конструкции множеств.

Любой способ, например, создать набор мощности или "экспоненциальное" перекрестное соединение "(каждая строка соединена с копиями самого себя size_in_rows)? Или какая-то рекурсия?

Пример того, что мне нужно:

У меня есть таблица с парой полей, каждое из которых содержит информацию и целое значение "count". Мне нужно ВЫБРАТЬ __ и отправить столько "подсчитать" копии одной и той же строки, чтобы прочитать ее одну за другой с другой программой за пределами базы данных.

3 ответа

Решение

Вот подход для SQL Server: Пример Fiddle

declare @rowToBeCopiedId bigint = 1
, @count int = 10

; with noRowsToInsertCte
(
    select 1 x
    where @count > 0
    union all
    select x + 1
    from noRowsToInsertCte 
    where @count > x
)
insert MyTable (col1, col2)
select col1, col2
from MyTable
cross join noRowsToInsertCte
where id = @rowToBeCopiedId

Если вместо дублирования записей в базе данных вы просто хотите дублировать записи в наборе результатов, вы можете сделать это, как показано ниже. В этом примере используется столбец в данных, чтобы указать, сколько раз должна повторяться связанная запись, и используется представление, позволяющее легко повторно использовать эту логику:

create view vMyTableWithCount as
with innerCte as 
(
    select id
    , col1
    , col2
    , cnt
    , 1 i
    from MyTable
    where cnt > 0

    union all

    select id
    , col1
    , col2
    , cnt
    , i + 1
    from innerCte
    where i < cnt
) 
select *
from innerCte

Для большего контекста, пожалуйста, смотрите пример скрипки.

Вы не указали свою СУБД, но с PostgreSQL это действительно легко:

select t.*
from the_table t
  cross join generate_series(1, t.count)
order by t.id

Предполагая, что столбец первичного ключа таблицы назван id, затем order by t.id хранит "дублированные" строки вместе.

Что-то вроде

SELECT * FROM T
UNION ALL
SELECT * FROM T WHERE count>1
UNION ALL
SELECT * FROM T WHERE count>2

должен доставить вас туда, но быстро становится непрактичным, если вы хотите, чтобы безумные подсчеты также работали.

Еще кое-что: вы не создаете наборы, вы создаете сумки. Наборы не могут иметь дубликаты по определению.

Перекрестное объединение не подходит для вашей цели, потому что оно производит больше столбцов, в которых вы находитесь после создания большего количества строк.

Другие вопросы по тегам