Таблица является:
+----+------+
| Id | Name |
+----+------+
| 1 | aaa |
| 1 | bbb |
| 1 | ccc |
| 1 | ddd |
| 1 | eee |
+----+------+
Требуемый выход:
+----+---------------------+
| Id | abc |
+----+---------------------+
| 1 | aaa,bbb,ccc,ddd,eee |
+----+---------------------+
Запрос:
SELECT ID,
abc = STUFF(
(SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, ''
)
FROM temp1 GROUP BY id
Этот запрос работает правильно. Но мне просто нужно объяснение, как это работает, или есть какой-то другой или короткий способ сделать это.
Я очень смущен, чтобы понять это.
sql
sql-server
database
Пунит Чавла
источник
источник
ID
он уникален в другой таблице разных сущностей, и эта таблица хранит вещи, которые принадлежат им.Ответы:
Вот как это работает:
1. Получить строку XML-элемента с FOR XML
Добавление FOR XML PATH в конец запроса позволяет выводить результаты запроса в виде элементов XML с именем элемента, содержащимся в аргументе PATH. Например, если мы запустим следующий оператор:
Передавая пустую строку (FOR XML PATH ('')), мы получаем следующее:
2. Удалите начальную запятую с помощью STUFF
Оператор STUFF буквально «вставляет» одну строку в другую, заменяя символы в первой строке. Однако мы используем его просто для удаления первого символа из результирующего списка значений.
Параметры
STUFF
:Итак, мы заканчиваем с:
3. Присоединяйтесь по id, чтобы получить полный список
Затем мы просто присоединяем это к списку идентификаторов во временной таблице, чтобы получить список идентификаторов с именем:
И у нас есть наш результат:
Надеюсь это поможет!
источник
LISTAGG
функцию в Oracle 11gR2. Я скучаю по этой функциональности в те дни, когда я должен использовать это вместо. techonthenet.com/oracle/functions/listagg.phplist
функционирует десятилетиями. К сожалению, Microsoft основала SQLServer на Sybase ASE и никогда не беспокоилась о функции списка до прошлого года. Я согласен - это ошеломляет. И тогда они делают, они называют этоstring_agg
. Я бы подумал, чтоlist
это довольно очевидно.В этой статье рассматриваются различные способы объединения строк в SQL, в том числе улучшенная версия кода, которая не кодирует XML-данные сцепленных значений.
Чтобы понять, что происходит, начните с внутреннего запроса:
Поскольку вы указываете
FOR XML
, вы получите одну строку, содержащую фрагмент XML, представляющий все строки.Поскольку вы не указали псевдоним столбца для первого столбца, каждая строка будет заключена в элемент XML с именем, указанным в скобках после
FOR XML PATH
. Например, если бы вы имелиFOR XML PATH ('X')
, вы получите XML-документ, который выглядел бы так:Но, так как вы не указали имя элемента, вы просто получаете список значений:
Он
.value('.', 'varchar(max)')
просто извлекает значение из полученного фрагмента XML, без кодирования XML каких-либо «специальных» символов. Теперь у вас есть строка, которая выглядит следующим образом:Затем
STUFF
функция удаляет начальную запятую, давая вам окончательный результат, который выглядит следующим образом:На первый взгляд это выглядит довольно запутанно, но, как и в некоторых других вариантах, имеет тенденцию работать довольно хорошо.
источник
TYPE
xml
nvarchar(max)
name
TYPE
и.value('.', 'varchar(max)')
, то в результате вы можете получить закодированные в формате XML объекты.Режим PATH используется при генерации XML из запроса SELECT
Выходные данные - это элементно-ориентированный XML, где каждое значение столбца в результирующем наборе строк заключено в элемент строки. Поскольку в предложении SELECT не указываются псевдонимы для имен столбцов, сгенерированные имена дочерних элементов совпадают с именами соответствующих столбцов в предложении SELECT.
Для каждой строки в наборе строк добавляется тег.
Для шага 2: если вы укажете строку нулевой длины, элемент переноса не будет создан.
На шаге 4 мы объединяем значения.
На шаге 6 мы группируем дату по идентификатору.
STUFF (source_string, start, length, add_string) Параметры или Аргументы source_string Исходная строка для изменения. start Позиция в source_string для удаления длинных символов, а затем вставьте add_string. длина Количество символов, которые нужно удалить из исходной строки. add_string Последовательность символов для вставки в source_string в начальной позиции.
источник
','
указанный столбец as в сочетании с('')
путем после XML вызывает конкатенациюSELECT 'a' FROM some_table FOR XML PATH('')
будет производить:'aaaaaaa'
. Но если будет указано имя столбца:SELECT 'a' AS Col FROM some_table FOR XML PATH('')
вы получите результат:<Col>a</Col><Col>a</Col><Col>a</Col>
В базе данных SQL Azure и SQL Server появилась очень новая функциональность (начиная с 2017 года) для обработки этого точного сценария. Я полагаю, что это послужит родным официальным методом для того, чего вы пытаетесь достичь с помощью метода XML / STUFF. Пример:
STRING_AGG - https://msdn.microsoft.com/en-us/library/mt790580.aspx
РЕДАКТИРОВАТЬ: Когда я первоначально опубликовал это, я упомянул SQL Server 2016, как я думал, я видел это на потенциальной функции, которая должна была быть включена. Либо я вспомнил, что неправильно, либо что-то изменилось, спасибо за предложенную редакцию, исправляющую версию. Кроме того, это произвело большое впечатление на меня, и он не был полностью осведомлен о многоэтапном процессе проверки, который просто потянул меня за окончательным вариантом.
источник
В
for xml path
, если мы определим любое значение , как[ for xml path('ENVLOPE') ]
то эти теги будут добавлены в каждой строке:источник
Здесь в вышеприведенном запросе функция STUFF используется, чтобы просто удалить первую запятую
(,)
из сгенерированной строки XML,(,aaa,bbb,ccc,ddd,eee)
после чего она станет(aaa,bbb,ccc,ddd,eee)
.И
FOR XML PATH('')
просто преобразует данные столбца в(,aaa,bbb,ccc,ddd,eee)
строку, но в PATH мы передаем '', чтобы он не создавал тег XML.И в конце мы сгруппировали записи, используя столбец ID .
источник
Я сделал отладку и, наконец, вернул свой «заполненный» запрос на него, это нормальный способ.
Просто
дает мне содержимое таблицы для записи в таблицу журнала из отлаженного триггера.
источник
источник
STUFF ((ВЫБЕРИТЬ разные ',' + CAST (T.ID) ИЗ таблицы T, где T.ID = 1 FOR XML PATH ('')), 1,1, '') AS Name
источник
Я часто использую с предложением где
источник