오케이 태그가 붙은 오라클을 알고 있으므로 자신이나 다른 오라클 전문가가이 솔루션을 SQL Server에서 마이그레이션 할 수 있습니다. 나는 오라클이 이러한 각각의 작업을 수행 할 수 있다는 것을 알고 있습니다.
일반적으로 나는 문자열을 분할하는 빠르고/멋진 방법을 원하지만,이 경우 분리 문자 사이에서 문자열의 서수 위치를 유지해야한다고 말하고 싶습니다. 그래서 네가 할 수있는 방법을 생각 했어.
1) 먼저 CSV를 모든 1 열로 임시 테이블에 가져옵니다. 이제 CRLF가 Name 열에서 발견되는 경우 문제가 될 수 있습니다 .... 그러나 사용자가 지정하지 않았기 때문에 그렇지 않은 것으로 가정합니다.
2) 가짜 기본 키로 사용할 테이블에 row_number를 빌드하고 구분 기호가 더 많이 있어야하는시기를 결정하십시오.
3) 재귀 cte를 사용하여 문자열을 행에 유출하고 원래 문자열에서 부분 문자열의 순서를 유지하여 나중에 연결합니다.
4) 결정에 기초를 두는 DENSE_RANK()를 MergePositions 의해 OrdinalPostion을 변경하고 생성하여 그룹에 어떤 행
5) 모든 OrdginalGroup을 결합하는 연결 수단을 사용해서 열 번호로하고 OrdinalGroup을 사용하여 조건부 집계 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