#sql #sql-server #xml #tsql #sql-server-2016
Вопрос:
Привет всем, у меня есть вопрос об объединении подобных идентификаторов, которые также имеют столбец XML.
Мои данные я пытаюсь объединить:
_ID _xml _indivisualCommaList _eachIndividual
------ ------------------------------------------------------------------------------------------------- ----------------------- ---------------
46589 <Individual><TBS>768-hER-382</TBS><Categories /><TBS2>768-hER-382,908-YTY-354</TBS2></Individual> 768-hER-382,908-YTY-354 768-hER-382
46589 <Individual><TBS>768-hER-382</TBS><Categories /><TBS2>768-hER-382,908-YTY-354</TBS2></Individual> 768-hER-382,908-YTY-354 908-YTY-354
Где
_ID = INT
_xml = XML
_индивизуалькоммалист = VARCHAR(МАКС)
_eachIndividual = VARCHAR(МАКС)
Красивый (легче читаемый) XML сверху:
<Individual>
<TBS>768-hER-382</TBS>
<Categories />
<TBS2>768-hER-382,908-YTY-354</TBS2>
</Individual>
<Individual>
<TBS>768-hER-382</TBS>
<Categories />
<TBS2>768-hER-382,908-YTY-354</TBS2>
</Individual>
XML, идентификатор и _indivisualcommerce всегда будут одинаковыми, независимо от того, сколько строк вернется обратно. Единственным уникальным столбцом будет _eachIndividual.
Поэтому я пытаюсь выполнить следующий запрос, чтобы сгруппировать подобные идентификаторы вместе
SELECT
*
FROM
@tblData
WHERE
_ID = @AssetID
GROUP BY
_ID
Естественно, из-за моего столбца XML я получаю ошибку:
Столбец «@tblData._xml » недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY.
Так что я действительно не уверен, что я могу сделать, чтобы объединить эти строки?
Конечный результат, которого я жду, — это:
_ID _xml _indivisualCommaList _eachIndividual
------ ------------------------------------------------------------------------------------------------- ----------------------- -----------------------
46589 <Individual><TBS>768-hER-382</TBS><Categories /><TBS2>768-hER-382,908-YTY-354</TBS2></Individual> 768-hER-382,908-YTY-354 768-hER-382,908-YTY-354
ИТАК, возможно ли это сделать?
Комментарии:
1. «XML, идентификатор и _indivisualCommaList всегда будут одинаковыми» — затем объедините _eachIndividual только по идентификатору и присоедините его обратно.
2. @Serg Не против показать пример этого?
3. Смотрите ответ.
4. XML нужен корневой узел, что вам здесь нужно?
Ответ №1:
Если я все правильно понял и для данного _ID
только _eachIndividual
меняется
select top(1) with ties t._ID, t._xml, t._indivisualCommaList, t2.x as _eachIndividual
from tbl t
join (select _ID, string_agg(_eachIndividual, ',') x
from tbl
group by _ID) t2 on t._ID = t2._ID
order by row_number() over(partition by t._ID order by t._ID)
Использование for xml path
агрегации в более старых версиях
select top(1) with ties t._ID, t._xml, t._indivisualCommaList,
stuff((select ',' t2._eachIndividual
from tbl t2
where t2._ID = t._ID
for xml path ('')),
1,1, '') _eachIndividual
from tbl t
order by row_number() over(partition by t._ID order by t._ID)
Комментарии:
1. Спасибо за пример. Я не могу использовать string_agg с моей версией SQL.
2. Сделайте это с
for xml path
альтернативой. Добавил и этот запрос.3. Кажется, работает хорошо. Тем не менее, я пытался не выполнять запрос, используя ТОП-1 .
4. Что
top(1)
конкретно не так сtop(1) with ties
этим?
Ответ №2:
Решение (с ужасной производительностью) без string_agg должно быть:
SELECT
dataA._id,
dataA._xml,
dataA._individualCommaList,
CONCAT(dataA._eachIndividual,',',dataB._eachIndividual) as _eachIndividual
FROM data dataA
JOIN data dataB ON dataA._id = dataB._id AND dataA._eachIndividual != dataB._eachIndividual
WHERE dataA._individualCommaList = CONCAT(dataA._eachIndividual,',',dataB._eachIndividual)
ПРИСОЕДИНИТЕ таблицу к себе, чтобы собрать необходимые данные в одну строку, но только присоединитесь к разным индивидуалам.
Предложения WHERE гарантируют, что будет сохранена запись в правильном порядке.
Альтернативно, вы могли бы использовать LIKE, чтобы сохранить строку из первого(?) индивидуала в списке.
Комментарии:
1. Это, кажется, работает, но, похоже, возникают проблемы, если в столбце _eachIndividual есть НУЛЬ или пробел .
2. Также кажется, что если строк больше 2, это ничего не показывает?