我想只列出几条记录(比如说3)并添加......如果使用FOR XML PATH('')在一行中有更多记录。
到目前为止,我已写过
;WITH SRC AS (
select 'A' grp, 'abc' rec
union select 'A', 'def'
union select 'A', 'ghi'
union select 'A', 'jkl'
union select 'B', 'mno'
)
SELECT (
SELECT STUFF((
SELECT TOP 3 ',' + rec FROM SRC
WHERE SRC.grp = tableA.grp
FOR XML PATH('')
), 1, 1, '') + CASE WHEN (SELECT COUNT(1) FROM SRC WHERE SRC.grp = tableA.grp) > 3 THEN ',...' ELSE '' END
)
FROM (SELECT 'A' grp) tableA
上述工作但我想知道是否有办法不从SRC中选择两次来完成作业(一个用于数据,一个用于计数),因为在某些情况下where子句可能是一个大的子句
我也不能将where子句移动到CTE中,因为条件取决于另一个选择的结果(例如从tableA中选择)。
使用MS SQL SERVER 2008 R2
谢谢
答案 0 :(得分:1)
使用组的前4行创建XML。粉碎前三个节点并返回第四行...
。
with SRC as
(
select 'A' grp, 'abc' rec
union select 'A', 'def'
union select 'A', 'ghi'
union select 'A', 'jkl'
union select 'B', 'mno'
union select 'B', 'pqr'
)
select (
select ','+S2.X.value('.', 'nvarchar(max)')
from (
select top(4) S.rec, '...' as eli
from SRC as S
where S.grp = tableA.grp
for xml path('X'), type
-- order by ?
) as S1(X)
cross apply S1.X.nodes('(X[position() lt 4]/rec, X[position() eq 4]/eli)/text()') as S2(X)
for xml path(''), type
).value('substring(text()[1], 2)', 'nvarchar(max)')
from (select 'A') as tableA(grp);
这是如何运作的?
最里面的查询使用前四行创建XML。
select top(4) S.rec, '...' as eli
from SRC as S
where S.grp = tableA.grp
for xml path('X'), type
-- order by ?
看起来像这样
<X>
<rec>abc</rec>
<eli>...</eli>
</X>
<X>
<rec>def</rec>
<eli>...</eli>
</X>
<X>
<rec>ghi</rec>
<eli>...</eli>
</X>
<X>
<rec>jkl</rec>
<eli>...</eli>
</X>
然后使用nodes()
S1.X.nodes('(X[position() lt 4]/rec, X[position() eq 4]/eli)/text()') as S2(X)
X[position() lt 4]/rec
为您提供前三个rec
节点的X
值,X[position() eq 4]/eli
为您提供eli
第四行的值。
将碎片XML作为表格的结果。
abc
def
ghi
...
然后使用for xml path
进行常规XML连接,并在substring(text()[1], 2)
子句中使用values()
删除第一个逗号。
另一种方式:
您可以在案例中使用row_number()
来确定我返回的第四行的时间。请注意,我在order by
函数和嵌套查询中都添加了row_number()
子句,以确保返回哪些行。
with SRC as
(
select 'A' grp, 'abc' rec
union select 'A', 'def'
union select 'A', 'ghi'
union select 'A', 'jkl'
union select 'B', 'mno'
union select 'B', 'pqr'
)
select (
select top(4) ','+case when row_number() over(order by S.rec) = 4 then '...' else S.rec end
from SRC as S
where S.grp = tableA.grp
order by S.rec
for xml path(''), type
).value('substring(text()[1], 2)', 'nvarchar(max)')
from (select 'A') as tableA(grp);