0

考虑下面的输入表需要帮助改善以下查询(CTE基础的解决方案)

Id CountryName 
1 India,Australia,Singapore,Pakistan,Bangaladesh 
2 Norway,Argentina,Brazil,WestIndies,Burma 

所需的输出是

Id Country1 Country2 Country3 Country4 Country5 
1 India Australia Singapore Pakistan Bangalades 
2 Norway Argentina Brazil WestIndies Burma 

我已经writen查询作为其下正常工作

;WITH cte AS (

SELECT 
Id, 
CAST('<i>' + REPLACE(CountryName, ',', '</i><i>') + '</i>' AS XML) AS names 
FROM @t 
) 

SELECT * FROM 
(
SELECT 
Id, 
x.i.value('.', 'VARCHAR(10)') AS Country, 
'Country' + CAST(s.Number AS VARCHAR) AS CountryType 
FROM cte 
CROSS APPLY master..spt_values s 
CROSS APPLY names.nodes('//i[position()=sql:column("s.number")]') x(i) 
WHERE s.type='p' 
) a 
PIVOT (
MAX(Country) FOR CountryType IN (Country1, Country2, Country3, Country4,Country5) 
) pvt 

但表现它是非常糟糕的... 我在寻找一个更好的查询,可以加快过程(这可能不是我的xquery方法,但是其他方法仅使用cTE而不使用RBar /过程/ while循环/光标方法)

即使我很好,如果我的查询可以改进。

N.B.〜我不能在表上添加任何索引。请考虑这一点作为对环境的限制。无论我需要做什么只是查询。

NB〜可以有更多的国家,而不是局限在5

请帮助....提前

感谢

回答

0

您可以使用parsename,如果你有相隔四个部分字符串.。既然你有五个国家,你可以得到先用一个普通字符串,然后删除第一个国家,.替换所有,和使用parsename为休息

declare @T table(Id int, CountryName varchar(50)) 
insert into @T values 
(1, 'India,Australia,Singapore,Pakistan,Bangaladesh'), 
(2, 'Norway,Argentina,Brazil,WestIndies,Burma') 

select Id, 
    substring(CountryName, 1, charindex(',', CountryName)-1) as Country1, 
    parsename(T.N, 4) as Country2, 
    parsename(T.N, 3) as Country3, 
    parsename(T.N, 2) as Country4, 
    parsename(T.N, 1) as Country5 
from @T 
    cross apply(select replace(stuff(CountryName, 1, charindex(',', CountryName), ''), ',', '.')) as T(N) 

如果你知道你有8个国家,你可以做这个。

declare @T table(Id int, CountryName varchar(100)) 
insert into @T values 
(1, 'India,Australia,Singapore,Pakistan,Bangaladesh,Denmark,Germany,France'), 
(2, 'Norway,Argentina,Brazil,WestIndies,Burma,South Africa,Spain,Portugal') 


select Id, 
    parsename(T1.N, 4) as Country1, 
    parsename(T1.N, 3) as Country2, 
    parsename(T1.N, 2) as Country3, 
    parsename(T1.N, 1) as Country4, 
    parsename(T2.N, 4) as Country5, 
    parsename(T2.N, 3) as Country6, 
    parsename(T2.N, 2) as Country7, 
    parsename(T2.N, 1) as Country8 
from @T 
    cross apply(select charindex(',', CountryName, charindex(',', CountryName, charindex(',', CountryName, charindex(',', CountryName)+1)+1)+1)) as S(P) 
    cross apply(select replace(substring(CountryName, 1, S.P-1), ',', '.')) as T1(N) 
    cross apply(select replace(stuff(CountryName, 1, S.P, ''), ',', '.')) as T2(N) 

如果您不知道有多少个国家需要动态构建查询。 The Curse and Blessings of Dynamic SQL