我只想列出几条记录(比如 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
谢谢
最佳答案
使用组的前 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()
粉碎 XMLS1.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()
为了弄清楚第四行我何时返回 a.请注意,我添加了一个 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);
关于sql - 仅显示前 n 条记录并添加 '...' FOR XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23753546/