我在名為 C0 的列中有逗號分隔的資料。
C0 中的資料如下所示:
| C0 |
|---|
| "Pacey LLC.",213830ZZ,11/1/2017,11/1/2017,"297,311.74","2,371.40",0.00,"1,325.18",0.00,42.22,"123,986. |
| Mike The Miker,9814140VCD,12/1/2018,12/1/2018,"3,917,751.99","419,743.54","36,642.66","344,090.43",0.00,"27,104.04" |
我希望它以這樣的方式結束:
| F1 | F1 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 |
|---|---|---|---|---|---|---|---|---|---|---|
| “佩西有限責任公司。” | 213830ZZ | 11/1/2017 | 11/1/2017 | 297,311.74 | 2,371.40 | 0.00 | 1,325.18 | 0.00 | 42.22 | 123,986.56 |
| 邁克邁克 | 9814140VCD | 12/1/2018 | 12/1/2018 | 3,917,751.99 | 419,743.54 | 36,642.66 | 344,090.43 | 0.00 | 10.00 | 2,434,671.06 |
我試過嵌套替換,但找不到一種模式來可靠地搜索而無需正則運算式,即 T/SQL?我也在這個家伙的 SSIS 中嘗試了TOKEN 方法,但都沒有成果。
嵌套替換方法卡在 1,000(如 0.00)以下的貨幣欄位上,而 SSIS TOKEN 方法假定所有欄位都以引號分隔,在我的示例中它們不是。
uj5u.com熱心網友回復:
正如您已經被告知的,TSQL 是錯誤的工具。盡管如此,這可以完成(至少對于給定的集合)。如果這是一次性操作,您可以嘗試一下。如果這是現實生活場景中重復發生的任務,我會嘗試以適當的格式獲取資料。
但是,這適用于給定的行:
DECLARE @t1 TABLE(ID INT IDENTITY, YourString NVARCHAR(1000));
INSERT INTO @t1 VALUES(N'"Pacey LLC.",213830ZZ,11/1/2017,11/1/2017,"297,311.74","2,371.40",0.00,"1,325.18",0.00,42.22,"123,986.56"')
,(N'Mike The Miker,9814140VCD,12/1/2018,12/1/2018,"3,917,751.99","419,743.54","36,642.66","344,090.43",0.00,10.00,"2,434,671.06"');
--您的資料包含特定于文化的格式的日期(真的很糟糕)--
最好切換到 ISO8601
--設定日期格式會有所幫助,但不推薦
SET DATEFORMAT dmy;
-- 第一個 cte 將APPLY與計算一起使用 -- 這TOP()
將允許一個一個地獲取每個單個字符。
WITH singleChars AS
(
SELECT t.ID
,A.Pos
,SUBSTRING(t.YourString,A.POs,1) AS CharOnPos
FROM @t1 t
CROSS APPLY(SELECT TOP (LEN(t.YourString)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values) A(Pos) --master..spt_values can be any table with sufficient rows
)
-- 我們繼續遞回cte
-- 它將遍歷字串并查找我們是否在參考區域內
,recCTE AS
(
SELECT *
,CASE WHEN CharOnPos='"' THEN 1 ELSE 0 END AS QuoteIsOpen
,CAST(CharOnPos AS NVARCHAR(MAX)) AS GrowingString
FROM singleChars WHERE Pos=1
UNION ALL
SELECT sc.ID,sc.Pos,sc.CharOnPos
,A.QuoteIsStillOpen
,CONCAT(GrowingString,CASE WHEN sc.CharOnPos=N',' AND A.QuoteIsStillOpen=0 THEN N'$%&' ELSE sc.CharOnPos END)
FROM singleChars sc
INNER JOIN recCTE r ON sc.ID = r.ID AND sc.Pos=r.Pos 1
CROSS APPLY(VALUES(CASE WHEN sc.CharOnPos='"' THEN CASE WHEN r.QuoteIsOpen=1 THEN 0 ELSE 1 END ELSE r.QuoteIsOpen END )) A(QuoteIsStillOpen)
)
--這個CTETOP 1 WITH TIES和ORDER BY一個磁區一起執行一個技巧ROW_NUMBER()
--結果將包括ID遞回的最終字串
,newlySeparated AS
(
SELECT TOP 1 WITH TIES * FROM recCTE
ORDER BY ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Pos DESC)
)
--finalSELECT使用了一個技巧來分割字串位置和型別安全
SELECT A.*
FROM newlySeparated ns
CROSS APPLY OPENJSON(CONCAT(N'[["',REPLACE(REPLACE(ns.GrowingString,'"',''),'$%&','","'),N'"]]'))
WITH(Company NVARCHAR(100) '$[0]'
,Code1 NVARCHAR(100) '$[1]'
,Date1 DATE '$[2]'
,Date2 DATE '$[3]'
,Decimal1 NVARCHAR(100) '$[4]' --Using a numbers type might work here, this depends on your machine
,Decimal2 NVARCHAR(100) '$[5]'
,Decimal3 NVARCHAR(100) '$[6]'
,Decimal4 NVARCHAR(100) '$[7]'
,Decimal5 NVARCHAR(100) '$[8]'
,Decimal6 NVARCHAR(100) '$[9]'
,Decimal7 NVARCHAR(100) '$[10]') A
OPTION(MAXRECURSION 0);
結果
---------------- ------------ ------------ ------------ -------------- ------------ ----------- ------------ ------ ------- --------------
| Pacey LLC. | 213830ZZ | 2017-01-11 | 2017-01-11 | 297,311.74 | 2,371.40 | 0.00 | 1,325.18 | 0.00 | 42.22 | 123,986.56 |
---------------- ------------ ------------ ------------ -------------- ------------ ----------- ------------ ------ ------- --------------
| Mike The Miker | 9814140VCD | 2018-01-12 | 2018-01-12 | 3,917,751.99 | 419,743.54 | 36,642.66 | 344,090.43 | 0.00 | 10.00 | 2,434,671.06 |
---------------- ------------ ------------ ------------ -------------- ------------ ----------- ------------ ------ ------- --------------
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/373180.html
標籤:sql sql-server 查询语句 解析 姐姐
