sql - 仅显示前 n 条记录并添加 '...' FOR XML

标签 sql sql-server-2008-r2

我只想列出几条记录(比如 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() 粉碎 XML

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()为了弄清楚第四行我何时返回 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/

相关文章:

tsql - 使用 T-SQL 创建表时,为什么最后一个字段后面的逗号不重要?

c# - 使用 POCO 类时,表名称映射在 EF 6 中不起作用

sql-server - 使用递归 CTE 计算预测平均值

mysql - 如何将 SQL 查询合并为整数?

sql - 如何将存储过程编写到文件中?

mysql - 如何在 MySQL 中返回数据透视表输出?

c# - EntityFramework 创建 130 多个连接

tsql - 从字符串转换日期和/或时间时转换失败错误

SQL Server TDE 和跨订阅恢复

mysql - 创建计算列时出现 "as"错误