okay Я знаю, что вы отметили oracle, поэтому, возможно, вы сами или другой Гуру Oracle может перенести это решение с SQL-сервера. Я знаю, что оракул способен на каждую из этих операций.
Обычно я бы сказал, что вам нужен быстрый/фантастический способ разделения строки, но в этом случае вам нужно поддерживать порядковое положение строк между разделителями. Поэтому я подумал о том, как вы могли бы это сделать.
1) Сначала импортируйте CSV в таблицу темп как все 1 столбец. теперь это будет проблемой, если ваш CRLF также находится в столбце Name ... но мы предположим, что это не потому, что вы не указали его.
2) Создайте row_number на этой таблице, чтобы использовать в качестве поддельного первичного ключа, и определите, когда есть больше разделителей, чем должно быть.
3) используйте рекурсивный cte, чтобы пролить строку в строки и сохранить порядковое положение подстроки в исходной строке, с которой позже будет конкатенация.
4) Определить, какие строки к группе путем изменения OrdinalPostion пути MergePositions и генерировании DENSE_RANK() на его основе
5) Условное Агрегирование с использованием OrdinalGroup как номер столбца, а затем использовать метод конкатенации, чтобы объединить все OrdginalGroup 3 ряда.
DECLARE @CSV as TABLE (LumpedColumns NVARCHAR(MAX))
INSERT INTO @CSV VALUES
('May 1st, 2015|Y|Jingle|he|imerscmidt|19901002|123456789|3')
,('May 1st, 2015|N|Jingleheimerscmidt|19901002|123456789|3')
,('May 5th, 2015|Y|Jon|19901001||1')
,('May 1st, 2015|N|Jon|19901002||1')
,('May 1st, 2015|Y|Jacob|19901001|234567890|2')
,('May 5th, 2015|N|Jingleheimerscmidt|19901001|123456789|3')
,('May 1st, 2015|Y|Jingleheimerscmidt|19901001|123456789|3')
;WITH cteFakePrimaryKey AS (
SELECT
LumpedColumns
,CASE WHEN LEN(LumpedColumns) - LEN(REPLACE(LumpedColumns,'|','')) > 5 THEN
LEN(LumpedColumns) - LEN(REPLACE(LumpedColumns,'|','')) - 5 ELSE 0 END as MergeXPositions
,ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as PK
FROM
@CSV
)
, cteRecursive AS (
SELECT
PK
,LumpedColumns
,MergeXPositions
,LEFT(LumpedColumns,CHARINDEX('|',LumpedColumns)-1) as ColValue
,RIGHT(LumpedColumns,LEN(LumpedColumns) - CHARINDEX('|',LumpedColumns)) as Remaining
,1 As OrdinalPosition
FROM
cteFakePrimaryKey
UNION ALL
SELECT
PK
,LumpedColumns
,MergeXPositions
,LEFT(Remaining,CHARINDEX('|',Remaining)-1)
,RIGHT(Remaining,LEN(Remaining) - CHARINDEX('|',Remaining))
,OrdinalPosition + 1
FROM
cteRecursive
WHERE
Remaining IS NOT NULL AND CHARINDEX('|',Remaining) > 0
UNION ALL
SELECT
PK
,LumpedColumns
,MergeXPositions
,Remaining
,NULL
,OrdinalPosition + 1
FROM
cteRecursive
WHERE Remaining IS NOT NULL AND CHARINDEX('|',Remaining) = 0
)
, cteOrdinalGroup AS (
SELECT
PK
,LumpedColumns
,ColValue
,OrdinalPosition
,DENSE_RANK() OVER (PARTITION BY PK ORDER BY
CASE
WHEN OrdinalPosition < 3 THEN OrdinalPosition
WHEN OrdinalPosition > (3 + MergeXPositions) THEN OrdinalPosition
ELSE 3 END) as OrdinalGRoup
FROM
cteRecursive
)
SELECT
PK
,LumpedColumns
,MAX(CASE WHEN OrdinalGRoup = 1 THEN ColValue END) as Date_Added
,MAX(CASE WHEN OrdinalGRoup = 2 THEN ColValue END) as this_flag
,STUFF(
(SELECT '|' + ColValue
FROM
cteOrdinalGroup g2
WHERE
g1.PK = g2.PK
AND g2.OrdinalGroup = 3
ORDER BY
g2.OrdinalPosition
FOR XML PATH(''))
,1,1,'') as name
,MAX(CASE WHEN OrdinalGRoup = 4 THEN ColValue END) as DOB
,MAX(CASE WHEN OrdinalGRoup = 5 THEN ColValue END) as SSN
,MAX(CASE WHEN OrdinalGRoup = 6 THEN ColValue END) as ID
FROM
cteOrdinalGroup g1
GROUP BY
PK
,LumpedColumns
ORDER BY
PK
без открытия файла? Вы имеете в виду, не открывая в текстовом редакторе, чтобы сделать это вручную? Файл должен быть открыт, чтобы прочитать его содержимое. Вы можете привести его как одно значение VARCHAR и вырезать строку на основе ваших собственных правил ... например, разбивать каждый столбец на несколько строк и определять, когда существует слишком много строк, а затем конкатенация строк и поворот назад в табличный формат – Matt
, если у вас есть контроль над генерацией файла csv, вы можете добавить классификаторы текста, например кавычки, так что трубы внутри текста не будут путаться с разделителями приложением (или вашим собственным кодом очистки данных) – Jayvee
Независимо от этого, вы должны открыть файл, чтобы изменить его - либо с помощью кода, либо вручную. – Missy