Предположим, эту таблицу:Как группировать конкатенацию нескольких столбцов?
PruchaseID | Customer | Product | Method
-----------|----------|----------|--------
1 | John | Computer | Credit
2 | John | Mouse | Cash
3 | Will | Computer | Credit
4 | Will | Mouse | Cash
5 | Will | Speaker | Cash
6 | Todd | Computer | Credit
Я хочу, чтобы сгенерировать отчет по каждому клиенту, что они купили, и их способы оплаты.
Но я хочу, что отчет будет одна строка для каждого клиента, например:
Customer | Products | Methods
---------|--------------------------|--------------
John | Computer, Mouse | Credit, Cash
Will | Computer, Mouse, Speaker | Credit, Cash
Todd | Computer | Credit
То, что я нашел до сих пор является групповой СЦЕПИТЬ с использованием метода XML PATH
, такие как:
SELECT
p.Customer,
STUFF(
SELECT ', ' + xp.Product
FROM Purchases xp
WHERE xp.Customer = p.Customer
FOR XML PATH('')), 1, 1, '') AS Products,
STUFF(
SELECT ', ' + xp.Method
FROM Purchases xp
WHERE xp.Customer = p.Customer
FOR XML PATH('')), 1, 1, '') AS Methods
FROM Purchases
Это дает мне результат, но меня беспокоит скорость этого.
На первый взгляд здесь происходит три разных выбора, по два будут умножаться на количество строк, которые имеют Покупки. В конечном итоге это будет замедляться.
Итак, есть ли способ сделать это с лучшей производительностью?
Я хочу добавить еще больше столбцов для агрегации, должен ли я делать этот блок STUFF() для каждого столбца? Это звучит недостаточно быстро для меня.
Siggestions?
Ну, вы денормализуете свои данные, чтобы сделать это, так что производительность будет потенциальной проблемой. Метод XML - лучший способ денормализации данных в список с разделителями. –
Будьте осторожны при использовании 'for xml path', это может вас удивить, если у вас есть, например,' & 'в ваших данных. Аарон Бертран сделал [сравнение] (http://sqlperformance.com/2014/08/t-sql-queries/sql-server-grouped-concatenation) различных методов, которые вы, возможно, захотите проверить. –