Неожиданно на tsql
Лень было писать pivot динамический, и число строк равно числу столбцов, опять же из ленности.
Задачка увы не решилась одним запросом так как CTE в памяти формируется по новой каждый раз, когда мы с ним соединяемся в предложении from. Если бы не необходимость сгенерировать столбики рандомно, можно было бы в один запрос написать.
declare @m int = 16
drop table if exists #n
;with z(n, c1, c2) as
(
select
n = 1
,c1 = a.c
,c2 = a.c
from (select replicate(N'■', abs(checksum(newid())) % @m) c ) a
union all
select
a.n1
,a.c2
,a.c2 + isnull(replicate(N'□', len(a.c1)-len(a.c2)) ,N'')
from
(
select
n1 = n+1
,c1 = z.c2
,c2 = replicate(N'■', abs(checksum(newid())) % @m )
from z where n < @m
) a
)
select * into #n from z
order by n desc
option (maxrecursion 100)
select left(c2,l) from #n z1
cross apply (select max(len(c1)) l from #n z2 where z2.n >= z1.n) x
order by n
И результат