Если вы спрашиваете, что я думаю, что вы просите, вы будете нуждаться в Dynamic SQL, регулярных выражений и поворачивающимися. Динамический SQL для генерации кода, который будет создавать таблицу с соответствующими столбцами (так как они названы в честь #___-
и их произвольное количество). Поворот для поворота столбца значений в строки на идентификатор.
Я привык к SQL Server, а не к Oracle, а возможности Regex, которые я использую, - это UDF, поскольку SQL Server не имеет собственных возможностей Regex. Поэтому мой ответ только поможет, но может дать вам представление о том, как подойти к этому.
Я полагаю, вы могли бы построили регулярное выражение UDF в Oracle, наше регулярное выражение UDF возвращает результат-набор, который я могу join
или в случае, если в SQL Server cross/outer apply
и это дает мне Value varchar
с всем матчем и SubMatches xml
с захваченным submatches:
create table #A (data varchar(100));
Insert into #A
values ('101,#abc-sds)dfgd)3453)#xyz-hju)dddjfj)eieei)2323');
Insert into #A
values ('102,#abc-ddeff)errr)3434)#xyz-bnhb)hehe)333)#abc-dew)weerr)2343)#efg-3434)34');
declare @cols nvarchar(max), @q nvarchar(max)
-- Gets found columns comma-separated in @cols:
select @cols = isnull(@cols + ', ', '') + substring(r.Value, 2, len(r.Value)-2)
from #A
cross apply dbo.RegexFind(data, '#(\w+)-', 1, 1, 1) r
group by r.Value
-- Dynamically create #B with @cols and insert
set @q = N'create table #B(id int, ' + replace(@cols, ', ', ' varchar(255), ') + ' varchar(255))
insert into #B
select p.*
from (
select r.Value,
a.SubMatches.value(''(//submatch[@index=0]/@value)[1]'', ''varchar(255)'') col,
a.SubMatches.value(''(//submatch[@index=1]/@value)[1]'', ''varchar(255)'') val
from #A
-- Find the ID at the start
cross apply dbo.RegexFind(data, ''^\d+'', 1, 1, 1) r
-- Find any and all #___- occurrences and the text after it
outer apply dbo.RegexFind(data, ''#(\w+)-([^#]+)'', 1, 1, 1) a
) s
pivot (-- Pivot dynamically on the found @cols
min(val) for col in (' + @cols + ')
) p
select * from #B'
exec sp_executesql @q
с вашим примером содержанием таблицы #A
это дает следующий SQL (содержание @q
):
create table #B(id int, abc varchar(255), efg varchar(255), xyz varchar(255))
insert into #B
select p.*
from (
select r.Value,
a.SubMatches.value('(//submatch[@index=0]/@value)[1]', 'varchar(255)') col,
a.SubMatches.value('(//submatch[@index=1]/@value)[1]', 'varchar(255)') val
from #A
-- Find the ID at the start
cross apply dbo.RegexFind(data, '^\d+', 1, 1, 1) r
-- Find any and all #___- occurrences and the text after it
outer apply dbo.RegexFind(data, '#(\w+)-([^#]+)', 1, 1, 1) a
) s
pivot (-- Pivot dynamically on the found @cols
min(val) for col in (abc, efg, xyz)
) p
select * from #B
Примечания Тхи ugh что эта таблица #B
temp существует только внутри динамического SQL, я не знаю, как Oracle справляется с этим.
Не понимаю, как разделить, что такое маркер, показать больше примеров и как разбить его. – zaratustra
Вы хотите разбить одну строку на несколько строк * и * столбцов? Почему значения xyz/efg для 102 повторяются в обеих строках - если '# abc' является началом следующей« строки », не будет ли одна строка получать xyz, а другая - efg? И как далеко вы достигли своей регулярной экспрессии? –