将多行连接成一个字符串

时间:2011-04-06 08:27:18

标签: sql-server sql-server-2008 string-concatenation

这是我在stackoverflow上提出的第一个问题,请耐心等待我:)

我在另一个帖子中问过它,因为它与该问题有关,但是被指示在一个新的问题线程中询问,所以在这里。

我有一个带有注释文本的表格,每行最多包含256个字符,这些字符按字段“linenumber”排序,但我不确定数据库中的亚麻布顺序是否按顺序排列。我将如何重新设计此查询以确保每个notesrecid按亚麻布排序?

在表NOTES_V上有一个名为“linenumber”的字段 - 我尝试通过notesrecid然后亚麻布命名BA别名,但在子查询中不允许排序。

我意识到极端和极不可能的情况下的结果可能会溢出8000个字符的varchar,但这是一个问题还是“只是”被截断为最多8000个字符?

SELECT A.DATASET, A.NOTESRECID, LEFT(A.NOTETXT,LEN(A.NOTETXT)-2) AS "NOTETXT", LEN(A.NOTETXT)-2 AS "#CHARS"
FROM (SELECT DISTINCT BB.DATASET, BB.NOTESRECID,
        (SELECT BA.TXT+', ' AS [text()]
         FROM NOTES_V BA
         WHERE BA.DATASET=BB.DATASET AND BA.NOTESRECID=BB.NOTESRECID
         ORDER BY BA.DATASET, BA.NOTESRECID
         FOR XML PATH (''))  [NOTETXT]
  FROM NOTES_V BB) A

下面编写的方法效果很好,但我遇到了CHAR(7)不可序列化的问题,所以稍微重写的查询在下面用空格替换CHAR(7)。

SELECT A.DATASET, A.NOTESRECID, A.NOTETXT, LEN(A.NOTETXT) AS "#CHARS"
FROM (SELECT BB.DATASET, BB.NOTESRECID,
      stuff((SELECT REPLACE(BA.TXT,CHAR(7),' ')+', ' AS [text()]
             FROM NOTES_V BA
             WHERE BA.DATASET=BB.DATASET AND BA.NOTESRECID=BB.NOTESRECID
             ORDER BY BA.DATASET, BA.NOTESRECID, BA.linenumber
             FOR XML PATH ('A'),type).value('.','nvarchar(max)'),1,2,'') [NOTETXT]
             FROM NOTES_V BB
             GROUP BY BB.DATASET, BB.NOTESRECID) A 

感谢您的帮助,非常感谢。

1 个答案:

答案 0 :(得分:1)

SELECT A.DATASET, A.NOTESRECID, A.NOTETXT, LEN(A.NOTETXT) AS "#CHARS"
FROM (SELECT BB.DATASET, BB.NOTESRECID,
        stuff((SELECT BA.TXT+', ' AS [text()]
         FROM NOTES_V BA
         WHERE BA.DATASET=BB.DATASET AND BA.NOTESRECID=BB.NOTESRECID
         ORDER BY BA.DATASET, BA.NOTESRECID, BA.linenumber
         FOR XML PATH ('A'),type).value('.','nvarchar(max)'),1,2,'') [NOTETXT]
  FROM NOTES_V BB
  GROUP BY BB.DATASET, BB.NOTESRECID) A

注意:

  • STUFF比LEFT或SUBSTRING更快
  • 如果您的NOTES_V.TXT数据包含将成为XML实体的字符,您将收到一些意外的文本。使用FOR XML, TYPE并从中提取值可确保不会发生这种情况
  • 我更喜欢GROUP BY,因为它在逻辑流方面优先于DISTINCT