Этот ответ не предназначен для того, чтобы показать лучший способ выполнения запроса - он предназначен для объяснения используемого вами запроса.
Для решения вашей проблемы вы должны использовать выражение where, как показано в примере с белкой его ответ вместо использования выражения case
.Нет смысла выбирать вещи, которые вам бесполезны.
Я вижу много путаницы в этом методе агрегирования строк - слишком много людей используют его, не понимая, что делает каждая его часть - так что здесь простоеобъяснение:
Этот метод состоит из трех частей:
агрегирует значения в столбцах.Вот что делает FOR XML PATH('')
.FOR XML PATH('')
вернет строку xml, где теги xml - это имя столбца (или псевдонимы) запроса.(см. столбцы cte_ForXml
и Aggregated
в примере сценария ниже).
Добавьте разделитель между значениями.Вот что делает ';' +
.Он также удаляет теги XML имени столбца из результатов - изменяя имя столбца на пустую строку.Пустые псевдонимы недопустимы в T-SQL, но путем объединения другого значения в столбце имя столбца больше нельзя использовать.
См. cte_ForXml_WithAnEmptyString
и OnlyValuesAggregated
в примере сценария.
Удалить лишний разделитель в начале строки.Вот что делает stuff
.
См. cte_FirstDlimiterRemoved
и FullQuery
в примере сценария.
Что stuff
делает, это вставляет строку в другую строку,в указанном index
, удаляя length
символов из исходной строки.Если вы вставляете пустую строку, вы просто удаляете часть, указанную параметрами index
и length
из исходной строки.
Пример сценария , чтобы проиллюстрировать различные шагиэтот метод агрегирования строк:
DECLARE @String_Agg AS TABLE
(
s varchar(10)
)
INSERT INTO @String_Agg (s) VALUES
('1'), ('2'), ('3')
;WITH cte_ForXml(Aggregated) AS
(
SELECT s
FROM @String_Agg
FOR XML PATH('')
)
, cte_ForXml_WithAnEmptyString(OnlyValuesAggregated) AS
(
SELECT '' + s
FROM @String_Agg
FOR XML PATH('')
)
, cte_ForXmlWithADelimiter(AggregatedWithADlimiter) AS
(
SELECT ';' + s
FROM @String_Agg
FOR XML PATH('')
), cte_FirstDlimiterRemoved(FullQuery) AS
(
SELECT STUFF
(
(
SELECT ';' + s
FROM @String_Agg
FOR XML PATH('')
), 1, 1, ''
)
)
SELECT Aggregated, OnlyValuesAggregated, AggregatedWithADlimiter, FullQuery
FROM cte_ForXml
CROSS JOIN cte_ForXml_WithAnEmptyString
CROSS JOIN cte_ForXmlWithADelimiter
CROSS JOIN cte_FirstDlimiterRemoved
Результаты:
Aggregated OnlyValuesAggregated AggregatedWithADlimiter FullQuery
<s>1</s><s>2</s><s>3</s> 123 ;1;2;3 1;2;3