好吧我知道你標記了oracle,所以也許你自己或另一個Oracle guru可以從sql-server遷移此解決方案。我知道oracle有能力進行這些操作。
通常我會說你想要一個快速/奇特的方式來分割一個字符串,但在這種情況下,你需要維護分隔符之間的字符串序號位置。所以我想到了一種可以做到這一點的方法。
1)首先將CSV導入臨時表中作爲全部1列。現在如果您的CRLF也在名稱列中找到,那麼這將成爲問題....但我們會認爲這不是因爲您沒有指定它。
2)在該表上構建一個row_number用作假主鍵,並確定何時存在的分隔符多於應該存在的分隔符。
3)使用遞歸cte將字符串溢出到行中,並在以後要連接的原始字符串中保留子字符串的序號位置。
4)確定由MergePositions改變OrdinalPostion併產生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