Возникли проблемы с путём FOR XML - без объединения - PullRequest
0 голосов
/ 16 января 2019

У меня есть ситуация, когда заказ может содержать несколько покупок лицензий - и если заказ действительно содержит несколько лицензий, я хочу отобразить описания лицензий в одной ячейке со значениями, разделенными запятыми. Если бы мы были на SQL 2017, я мог бы использовать STRING_AGG, но мы находимся на SQL 2016, поэтому я пробую и проверенный метод STUFF / FOR XML Path.

На приведенном ниже снимке экрана клиент 4341073 совершил две покупки лицензии по коду заказа 18519173: enter image description here

Когда я добавляю XML-путь STUFF / FOR к T-SQL, я не могу достичь желаемого результата, отображая описание лицензии в одной и той же записи - каждая лицензия по-прежнему имеет свою собственную строку.

SELECT   x.CustomerID ,
         x.ATOLicenseTypeID ,
         x.ATOLicense ,
         x.AuthorizationBeginDate ,
         x.AuthorizationEndDate ,
         x.OrderID ,
         x.OrderDate ,
         STUFF ( (
                 SELECT ',' + lt.description
                 FROM   dbo.LicenseTypes AS lt
                 --INNER JOIN #XMLPATH ON lt.id = x.OrderLicenseTypeID
                 WHERE  lt.id = x.OrderLicenseTypeID
                 --GROUP BY ',' + lt.description
                 FOR XML PATH ( '' )
             ) , 1 , 1 , '' ) AS Licenses
FROM     #XMLPATH AS x
--GROUP BY x.CustomerID ,
--         x.ATOLicenseTypeID ,
--         x.ATOLicense ,
--         x.AuthorizationBeginDate ,
--         x.AuthorizationEndDate ,
--         x.OrderID ,
--         x.OrderDate ,
--         x.OrderLicenseTypeID;

enter image description here

Я пробовал разные способы присоединения подзапроса к внешнему запросу и добавил и удалил GROUP BY для достижения желаемого результата, но у меня ничего не получается.

Есть предложения, где я ошибаюсь в этом запросе?

Пример набора данных:

DROP TABLE IF EXISTS #XMLPATH;

CREATE TABLE #XMLPATH
    (
        CustomerID INT ,
        ATOLicenseTypeID INT ,
        ATOLicense VARCHAR (500) ,
        AuthorizationBeginDate DATE ,
        AuthorizationEndDate DATE ,
        OrderID INT ,
        OrderDate DATETIME ,
        OrderLicenseTypeID INT
    );
INSERT INTO #XMLPATH
VALUES ( 4341073, 52, 'Temporary Resident Fishing', N'2019-01-07T00:00:00', N'2019-01-07T00:00:00', 18519136, N'2019-01-07T12:01:55.317', 2141 ) ,
       ( 4341073, 52, 'Temporary Resident Fishing', N'2019-01-07T00:00:00', N'2019-01-07T00:00:00', 18519173, N'2019-01-07T12:34:13.107', 204 ) ,
       ( 4341073, 52, 'Temporary Resident Fishing', N'2019-01-07T00:00:00', N'2019-01-07T00:00:00', 18519173, N'2019-01-07T12:34:13.107', 2141 );

SELECT * FROM #XMLPATH;

SELECT   x.CustomerID ,
         x.ATOLicenseTypeID ,
         x.ATOLicense ,
         x.AuthorizationBeginDate ,
         x.AuthorizationEndDate ,
         x.OrderID ,
         x.OrderDate ,
         STUFF ( (
                 SELECT ',' + lt.description
                 FROM   dbo.LicenseTypes AS lt
                 --INNER JOIN #XMLPATH ON lt.id = x.OrderLicenseTypeID
                 WHERE  lt.id = x.OrderLicenseTypeID
                 --GROUP BY ',' + lt.description
                 FOR XML PATH ( '' )
             ) , 1 , 1 , '' ) AS Licenses
FROM     #XMLPATH AS x
GROUP BY x.CustomerID ,
         x.ATOLicenseTypeID ,
         x.ATOLicense ,
         x.AuthorizationBeginDate ,
         x.AuthorizationEndDate ,
         x.OrderID ,
         x.OrderDate ,
         x.OrderLicenseTypeID;

1 Ответ

0 голосов
/ 20 января 2019

Чтобы получить все строки одной OrderID как одну строку результатов, вы не должны включать разделительную информацию (OrderLicenseTypeID) в GROUP BY.Но тогда у вас есть проблема, с которой вы столкнулись: вы не можете использовать этот идентификатор в вашей FOR XML конструкции.

Хитрость (как показывают ваши закомментированные испытания) - добавить исходную таблицу в подпрограмму.- выберите и отфильтруйте там сгруппированный столбецНо вы должны использовать разные псевдонимы, чтобы обращаться с ними как с двумя разными наборами.Попробуйте это:

(Мне пришлось добавить еще одну временную таблицу, чтобы проверить это ...)

SELECT   x.CustomerID ,
         x.ATOLicenseTypeID ,
         x.ATOLicense ,
         x.AuthorizationBeginDate ,
         x.AuthorizationEndDate ,
         x.OrderID ,
         x.OrderDate ,
         STUFF ( (
                 SELECT ',' + lt.description
                 FROM   #XMLPATH x2 
                 INNER JOIN #LicenseTypes AS lt ON lt.id=x2.OrderLicenseTypeID
                 WHERE  x2.OrderID = x.OrderID --you might need to add more columns here....
                 --in most cases we want to add an ORDER BY
                 FOR XML PATH ( '' )
             ) , 1 , 1 , '' ) AS Licenses
FROM     #XMLPATH AS x
GROUP BY x.CustomerID ,
         x.ATOLicenseTypeID ,
         x.ATOLicense ,
         x.AuthorizationBeginDate ,
         x.AuthorizationEndDate ,
         x.OrderID ,
         x.OrderDate;

Кстати: начиная с v2017, STRING_AGG () , что делает это намного проще ...

...