объединение строк в группе по функции с другими агрегатными функциями - PullRequest
7 голосов
/ 07 апреля 2011

Возможно ли объединить строки с одной или несколькими другими группами с помощью таких функций, как сумма, среднее, число и т. Д.

Скажем, у меня есть следующая таблица

Id Name Order Value  
1  a    1     100  
2  b    2     200  
3  c    1     300  
4  d    1     100  
5  e    2     300

Теперь, если яхочу, чтобы результат был чем-то в этом роде

Order Name   Value Count  
1     a,c,d  500   3  
2     b,e    500   2  

Как я могу добиться того же, используя запрос на сервере SQL.

Ответы [ 3 ]

7 голосов
/ 07 апреля 2011

Пример таблицы

create table t123 (Id int, Name varchar(10), [Order] int, Value int)
insert t123 select 
1,'a','1',100 union all select
2,'b','2',200 union all select
3,'c','1',300 union all select
4,'d','1',100 union all select
5,'e','2',300

Запрос для SQL Server 2005 и выше

select a.[order], STUFF((
    select ','+b.name
    from t123 b
    where b.[order] = a.[order]
    order by b.name
    for xml path('a'), type).value('.','nvarchar(max)'),1,1,'') Name,
    SUM(a.value) value,
    COUNT(*) [count]
from t123 a
group by a.[order]

Вывод

order       Name         value       count
----------- ------------ ----------- -----------
1           a,c,d        500         3
2           b,e          500         2
4 голосов
/ 08 апреля 2011

Попробуйте использовать это.

  • Я поместил ваш оригинальный запрос в CTE.
  • Затем я выбрал его и сгруппировал по порядку.
  • Затем я применил подзапрос, который получает разделенный запятыми набор имен для каждого заказа во внешнем запросе.
  • Поскольку я также выбрал столбец имен, мне пришлось также группировать по столбцу имен.

Как это:

;WITH cte(id, n, o, v) as (
   SELECT Id, Name, Order, Value FROM ....
)
SELECT o, names, SUM(v), COUNT(*)
FROM cte AS outer
CROSS APPLY (
    SELECT Name+',' 
    FROM cte AS inner 
    WHERE outer.o = inner.o 
    ORDER BY Name FOR XML PATH('')
) n(names)
group by o, names
1 голос
/ 08 апреля 2011

Если вы используете MS SQL Server 2005 или новее, вы можете создавать пользовательские агрегатные функции.

MSDN: СОЗДАТЬ АГРЕГАТ (Transact-SQL)

MSDN: вызов пользовательских функций CLR

...