SQL Server объединяет записи с агрегатной функцией в операторе select - PullRequest
3 голосов
/ 23 марта 2012

У меня есть представление vw_XC_DocInfo_1 со столбцами VId, VName, DocId, Amount, INum.Ниже приведены данные таблицы.

Vid   VName  DocId  Amount  INum
1     ABC     10     100    INV1
1     ABC     11     10     INV2
1     ABC     12     20     INV3
1     ABC     13     30     INV4
2     XYZ     14    200     INV5
2     XYZ     15     10     INV6
2     XYZ     16     20     INV7
2     XYZ     17     30     INV8

Мне нужно отобразить вывод, как показано ниже.

Vid   VName  DocIdsList  Amount  INumList
1     ABC    10,11       110     INV1,INV2
1     ABC    12,13       50      INV3,INV4
2     XYZ    14,15       210     INV5,INV6
3     XYZ    16,17       50      INV7,INV8

Я пробовал разные способы, но не смог включить функцию агрегирования с функцией STUFF, найдитезапрос у меня устал.

with CTE
as (
    select top 20 V.VendorId,
        V.VendorName,
        STUFF((
                select top 3 ',' + CONVERT(varchar(MAX), V1.DocumentId)
                from vw_XC_DocInfo_1 V1
                where V1.VendorID = V.VendorId
                order by V1.DocumentId
                for xml PATH('')
                ), 1, 1, '') as DocIdsList,
        STUFF((
                select top 3 ',' + CONVERT(varchar(MAX), V1.InvoiceNumber)
                from vw_XC_DocInfo_1 V1
                where V1.VendorID = V.VendorId
                order by V1.InvoiceNumber
                for xml PATH('')
                ), 1, 1, '') as InvNumList
    from vw_XC_DocInfo_1 V
    order by V.VendorID
    )
select VendorId,
    VendorName,
    DocIdsList,
    InvNumList
from CTE
group by VendorId,
    VendorName,
    DocIdsList,
    InvNumList

Ответы [ 4 ]

3 голосов
/ 23 марта 2012

Как насчет чего-то более нестандартного?

SELECT VendorId, VendorName,
  CASE WHEN COUNT(DocumentId)>1 
       THEN CAST(MIN(DocumentId) AS VARCHAR(MAX)) + ',' +
            CAST(MAX(DocumentId) AS VARCHAR(MAX))
       ELSE CAST(MIN(DocumentId) AS VARCHAR(MAX)) 
  END AS DocIdList,
  SUM(Amount) Amount,
  CASE WHEN COUNT(InvoiceNumber)>1
       THEN MIN(InvoiceNumber) + ',' + MAX(InvoiceNumber)
       ELSE MIN(InvoiceNumber)
  END AS INumList
FROM 
  (SELECT *,(ROW_NUMBER() OVER (PARTITION BY VendorId 
                                ORDER BY VendorId) - 1) / 2 AS seq
      FROM vw_XC_DocInfo_1) AS result
GROUP BY VendorId, VendorName, seq

Демо здесь .

1 голос
/ 23 марта 2012

Будет ли это работать для вас?

SELECT V.VendorId, 
       V.VendorName,
       STUFF((
            select ',' + CONVERT(varchar(MAX), V1.DocumentId)
            from vw_XC_DocInfo_1 V1
            where V1.VendorID = V.VendorId
            order by V1.DocumentId
            for xml PATH('')
            ), 1, 1, '') as DocIdsList,
       SUM(V.Amount) as AmountSums,
       STUFF((
            select ',' + CONVERT(varchar(MAX), V1.InvoiceNumber)
            from vw_XC_DocInfo_1 V1
            where V1.VendorID = V.VendorId
            order by V1.InvoiceNumber
            for xml PATH('')
            ), 1, 1, '') as InvNumList
FROM vw_XC_DocInfo_1 V
GROUP BY V.VendorId, V.VendorName
ORDER BY V.VendorId, V.VendorName

извините, у меня было много ошибок при наборе текста ... я думаю, что получил это благодаря Иоахиму Исакссону

0 голосов
/ 23 марта 2012
;with a
as
(
  select Vid,VName,DocId,Amount,INum, 
  row_number() over(partition by vid order by Inum) n 
  from vw_XC_DocInfo_1
)
select a.Vid, a.vname, 
cast(a.docid as varchar(3)) + coalesce(','+cast(b.docid as varchar(9)), '') docid, 
a.amount + coalesce(b.amount, 0) amount, 
a.INum + coalesce(',' + b.INum, '') INumList
from a left join a b on a.n + 1 = b.n and a.vid = b.vid
where a.n%2 = 1
0 голосов
/ 23 марта 2012

вы можете посмотреть на коалесцию - http://www.mssqltips.com/sqlservertip/1521/the-many-uses-of-coalesce-in-sql-server/

но после непродолжительной охоты - думаю, здесь поможет вопрос: Объединить много строк в одну текстовую строку?

Посмотрите на ответ Ритеша, который использует XML_Path

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...