2

其实我米begineer到SQL XML路径,以便使我的专业,有一个场景...... 我有一个CTE功能结果SQL XML路径转换结果错误

Data Chars NumberOfOccurance 
12 1 1 appears (1) times 
12 2 2 appears (1) times 
xx x x appears (2) times 

和CTE功能是:

;with cte as 
    (
     select Data , SUBSTRING(Data,1,1) as Chars,1 as startpos from @t 
     union all 
     select Data, SUBSTRING(Data, startpos+1,1) as char,startpos+1 from cte where startpos+1<=LEN(data) 
    ) 
    select Data,Chars,Cast(Chars as varchar(1)) + ' appears (' + cast(COUNT(*) as varchar(5))+ ') times' as 'NumberOfOccurance' from cte 
    group by data, chars 

其实我只想让我的回答这个:

data Number_of_occurances 
12 1 appears (1) times 2 appears (1) times 
xx x appears (2) times 

我公顷已经尝试这样的:

; With Ctea as 
(
select Data , SUBSTRING(Data,1,1) as Chars,1 as startpos from @t 
    union all 
    select Data, SUBSTRING(Data, startpos+1,1) as char,startpos+1 from ctea where startpos+1<=LEN(data) 
) 
select Data,Chars,REPLACE((SELECT (Cast(Chars as varchar(1)) + ' appears (' + cast(COUNT(*) as varchar(5))+ ') times') AS [data()] FROM Ctea t2 WHERE t2.Data = t1.data FOR XML PATH('')), ' ', ' ;') As Number_of_occurances from ctea as t1 
group by t1.data, t1.Chars 

它说:

Column 'Ctea.Chars' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 

当我使用临时表,并让我确切的答案,但不能做它CTE

谁能让我的结果?

回答

0

您可以使用FOR XML PATH这样的级联

;with cte as 
    (
     select Data , SUBSTRING(Data,1,1) as Chars,1 as startpos from @t 
     union all 
     select Data, SUBSTRING(Data, startpos+1,1) as char,startpos+1 from cte where startpos+1<=LEN(data) 
    ), CTE2 AS 
    (
    select Data,Chars,Cast(Chars as varchar(1)) + ' appears (' + cast(COUNT(*) as varchar(5))+ ') times' as 'NumberOfOccurance' from cte 
    group by data, chars 
    ) 
    SELECT Data,(SELECT NumberOfOccurance + ' ' FROM CTE2 c2 WHERE c2.Data = C1.Data FOR XML PATH(''),type).value('.','VARCHAR(MAX)') as Number_of_occurances 
    FROM CTE2 C1 
    GROUP BY Data 
2

的问题无关,与你的CTE。实际上,它主要表现在以下子查询:

SELECT (Cast(Chars as varchar(1)) + 
    ' appears (' + 
    cast(COUNT(*) as varchar(5)) + 
    ') times') AS [data()] 
FROM Ctea t2 
WHERE t2.Data = t1.data 
FOR XML PATH('') 

注意你是如何在这里使用聚合COUNT(*)以及列Chars。您需要按至少Chars这里:

SELECT (Cast(Chars as varchar(1)) + 
    ' appears (' + 
    cast(COUNT(*) as varchar(5)) + 
    ') times') AS [data()] 
FROM Ctea t2 
WHERE t2.Data = t1.data 
GROUP BY t2.Chars 
FOR XML PATH('') 

此外,你t1.Chars外部查询选择或组,因为它会导致每个字符数的值一行:

 
data chars Number_of_occurances 
12 1  1 appears (1) times 2 appears (1) times 
12 2  1 appears (1) times 2 appears (1) times 
xx x  x appears (2) times 

最后,你应该最有可能被使用STUFF function,而不是REPLACE,因为你正试图创造一个空间分隔的列表(“1出现(1)次2次出现(1)次”),而不是取代所有的空间带有空格和分号的字符(“1;出现;(1);次数; 2;出现;(1);次数”)。

所以你最终的查询应该是:

; With Ctea as 
(
    select Data , SUBSTRING(Data,1,1) as Chars,1 as startpos from @t 
    union all 
    select Data, SUBSTRING(Data, startpos+1,1) as char,startpos+1 from ctea 
    where startpos+1<=LEN(data) 
) 
select Data, 
    STUFF((SELECT cast(' ' as varchar(max)) + (Cast(Chars as varchar(1)) + ' appears (' + cast(COUNT(*) as varchar(5))+ ') times') AS [data()] 
      FROM Ctea t2 
      WHERE t2.Data = t1.data 
      GROUP BY t2.Chars 
      FOR XML PATH('')), 1, 1, '') As Number_of_occurances 
from ctea as t1 
group by t1.data