我遇到一个问题,我有一个存储名称和地址的nvarchar
列,但字符串中有CR。我设法追踪显示空白区域的功能。
示例如下
Mr[?]John[?]Spartan[CR][LF]36[?]Kendrick[?]Road[CR][LF]Birmingham[CR][LF]B3[?]7SA[CR][LF][CR][LF]
我发现了很多关于csvs和其他一些解决方案的帖子,这些解决方案分成了我试图复制的不同行但是还没有能够得到任何有用的东西。
最终结果将是4列而不是1。
Address 1 | Address 2 | Address 3 | Address 4
Mr John Spartan | 36 Kendrick Road | Birmingham | B3 7SA
希望我对我的问题已经足够清楚了。
答案 0 :(得分:0)
如果要转换为列,请尝试此操作。我在查询中编写了逻辑。
DECLARE @STR NVARCHAR(MAX)='Mr[?]John[?]Spartan[CR][LF]36[?]Kendrick[?]Road[CR][LF]Birmingham[CR][LF]B3[?]7SA[CR][LF][CR][LF]'
-- Convert to CSV
SELECT @STR = LEFT(REPLACE(REPLACE(@STR,'[?]',' '),'[CR][LF]',' , '),
LEN(REPLACE(REPLACE(@STR,'[?]',''),'[CR][LF]',' , ')))
;WITH CTE AS
(
-- Split to rows and create a row to set default Row_Number()
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) RNO,
LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'Address'
FROM
(
-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
SELECT CAST ('<M>' + REPLACE(@STR, ',', '</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
-- Convert to columns
SELECT
MIN(CASE WHEN RNO=1 THEN [Address] END) [Address1],
MIN(CASE WHEN RNO=2 THEN [Address] END) [Address2],
MIN(CASE WHEN RNO=3 THEN [Address] END) [Address3],
MIN(CASE WHEN RNO=4 THEN [Address] END) [Address4]
FROM CTE
<强> RESULT 强>
编辑:
如果您从表格中的列中选择字符串,则可以按照以下步骤操作。
样本表
CREATE TABLE #TEMP(STRINGCOL NVARCHAR(MAX))
INSERT INTO #TEMP
SELECT 'Mr[?]John[?]Spartan[CR][LF]36[?]Kendrick[?]Road[CR][LF]Birmingham[CR][LF]B3[?]7SA[CR][LF][CR][LF]'
UNION ALL
SELECT 'Mrs[?]Smith[?]Tisut[CR][LF]12[?]Criss[?]Road[CR][LF]Birmingham[CR][LF]C4[?]6UI[CR][LF][CR][LF]'
<强> QUERY 强>
;WITH CTE AS
(
-- Since, its splitting to CSV, we need to get a unique id for those items which was in row
SELECT ROW_NUMBER() OVER(PARTITION BY RNO ORDER BY (SELECT 0)) RNO2,RNO,
LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'Address'
FROM
(
-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
SELECT RNO,CAST ('<M>' + REPLACE(REPLACE(REPLACE(STRINGCOL,'[?]',' '),'[CR][LF]',' , ')
, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM
(
-- Select Row_Number for each row
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) RNO, STRINGCOL
FROM #TEMP
)TAB
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
SELECT RNO,
MIN(CASE WHEN RNO2=1 THEN [Address] END) [Address1],
MIN(CASE WHEN RNO2=2 THEN [Address] END) [Address2],
MIN(CASE WHEN RNO2=3 THEN [Address] END) [Address3],
MIN(CASE WHEN RNO2=4 THEN [Address] END) [Address4]
FROM CTE
GROUP BY RNO
答案 1 :(得分:0)
与@SarathAvanavu类似,但使用PIVOT;
declare @table table (id int not null, NameAndAddress varchar(max) not null)
insert @table values (1, 'Mr John Spartan|36 Kendrick Road|Birmingham|B3 7SA')
insert @table values (2, 'Mrs Victoria Smith|72 Domino Avenue|Leicester|LE1 7RE')
insert @table values (3, 'Miss Sarah Parker|48 Lilly Lane|Bedford|BE2 6TE')
; with cte as (
select
id,
cast('<column>' + replace(NameAndAddress, '|', '</column><column>') + '</column>' as xml) as XmlNameAndAddress
from
@table
)
select id, [1] as Column1, [2] as Column2, [3] as Column3, [4] as Column4
from
(
select
id,
row_number() over(partition by id order by (select 0)) as rn,
Split.a.value('.', 'varchar(1024)') as Value
from
cte
cross apply XmlNameAndAddress.nodes ('/column') as Split(a)
) AS SourceTable
pivot
(
min(Value)
for rn in ([1], [2], [3], [4])
) as PivotTable