Есть ли способ дублировать строку?
Я хочу что-то, что работает противоположно COUNT, это как обратное GROUP BY
(а SPLIT 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
должен доставить вас туда, но быстро становится непрактичным, если вы хотите, чтобы безумные подсчеты также работали.
Еще кое-что: вы не создаете наборы, вы создаете сумки. Наборы не могут иметь дубликаты по определению.
Перекрестное объединение не подходит для вашей цели, потому что оно производит больше столбцов, в которых вы находитесь после создания большего количества строк.