SQLXML路径转换结果错误

SQL XML path conversion results error

实际上我是 SQL XML 道路的初学者,因此让我变得专业,得到了一个场景...... 我有一个 CTE 函数结果为

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.

当我使用临时 table 并得到我的确切答案时,但无法做到 CTE

谁能做出我的结果?

你可以像这样使用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

问题与您的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('')

此外,您 想要 select 或在外部查询中按 t1.Chars 分组,因为它会导致每个 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,因为您正在尝试创建一个 space 分隔列表 ("1出现 (1) 次 2 次出现 (1) 次 "),而不是将所有 space 字符替换为 space 和分号 ("1 ;appears ;( 1) ;times ;2 ;appears ;(1) ;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,
    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