Объединение нескольких строк в одну строку - PullRequest
1 голос
/ 06 апреля 2011

Это мой первый вопрос, заданный здесь в stackoverflow, поэтому потерпите меня, пожалуйста:)

Я задал его в другой ветке, поскольку он был связан с этим вопросом, но мне было предложено задать в новой ветке вопросоввот оно.

У меня есть таблица с текстами заметок, каждая строка которых содержит не более 256 символов, они упорядочены по полю «белья», но я не уверен, что порядок белья вБаза данных находится в последовательности.Как бы я изменил дизайн этого запроса, чтобы обеспечить упорядочение по номеру белья для каждого примечания recid?

В таблице NOTES_V есть поле с именем «белья» - я попытался упорядочить 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 Ответ

1 голос
/ 06 апреля 2011
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 с точки зрения логического потока
...