Можно ли иметь несколько столбцов String_Agg с условиями - PullRequest
0 голосов
/ 30 января 2019

У меня есть следующая таблица регистрации событий.В таблице многодневные события записываются в виде отдельной записи для каждой зарегистрированной даты.Кроме того, если дата заполнена, ее еще можно зарегистрировать в качестве даты ожидания.Я пытаюсь создать одну запись из записи в таблице ниже, где даты агрегируются строки.Таблица, показанная ниже, а также несколько связанных таблиц более сложны, чем эта, но я упростил для примера.

Таблица EventAssignments

+--------+---------+----------+--------+------------+
| UserID | EventID | AssignID | DateID | WaitListed |
+--------+---------+----------+--------+------------+
|      1 |      19 |       14 |     67 |          0 |
|      1 |      19 |       14 |     68 |          0 |
|      1 |      19 |       14 |     69 |          1 |
+--------+---------+----------+--------+------------+ 

Таблица EventDates

+--------+-------------------------+---------+------------+
| DateID |        EventDate        | EventID | DateTypeID |
+--------+-------------------------+---------+------------+
|     65 | 2019-03-20 00:00:00.000 |      19 |          1 |
|     66 | 2019-03-21 00:00:00.000 |      19 |          1 |
|     67 | 2019-03-22 00:00:00.000 |      19 |          2 |
|     68 | 2019-03-23 00:00:00.000 |      19 |          2 |
|     69 | 2019-03-24 00:00:00.000 |      19 |          2 |
|     70 | 2019-03-25 00:00:00.000 |      19 |          3 |
+--------+-------------------------+---------+------------+

Желаемые результаты запроса должны выглядеть следующим образом:

+--------+---------+----------+----------------------------+---------------+
| UserID | EventID | AssignID |      RegisteredDates       | WaitListDates |
+--------+---------+----------+----------------------------+---------------+
|      1 |      19 |       14 | 03/22/2019<br />03/23/2019 | 03/24/2019    |
+--------+---------+----------+----------------------------+---------------+

Я думал, что мне нужна некоторая логика, поэтому я попытался реализовать использование CASE, как показано ниже.Результаты, однако, по-прежнему отображаются в виде двух записей.первая запись для обычных дат, а вторая для дат ожидания в списке

SELECT a.UserID, a.EventID, a.AssignID, 
(CASE WHEN a.WaitListed = 'false' 
    THEN STRING_AGG(CONVERT(varchar, d.EventDate, 101), '<br />') END) AS RegDates, 
(CASE WHEN a.WaitListed = 'true' 
    THEN STRING_AGG(CONVERT(varchar, d.EventDate, 101), '<br />') END) AS WaitListDates
FROM dbo.EventAssignments AS a 
INNER JOIN dbo.EventDates AS d ON a.DateID = d.DateID
GROUP BY a.UserID, a.EventID, a.WaitListed, a.AssignID

Ответы [ 2 ]

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

Попробуйте этот запрос:

SELECT a.UserID, 
       a.EventID, 
       a.AssignID, 
STRING_AGG(CASE WHEN a.WaitListed = 'false' 
    THEN CONVERT(varchar, d.EventDate, 101) END, '<br />') AS RegDates, 
STRING_AGG(CASE WHEN a.WaitListed = 'true' 
    THEN CONVERT(varchar, d.EventDate, 101) END, '<br />') AS WaitListDates
FROM dbo.EventAssignments AS a 
INNER JOIN dbo.EventDates AS d 
  ON a.DateID = d.DateID
GROUP BY a.UserID, a.EventID, a.AssignID

Результат:

UserID  EventID AssignID    RegDates                    WaitListDates
1       19      14          03/22/2019<br />03/23/2019  03/24/2019
0 голосов
/ 30 января 2019

Я виноват в том, что пропустил последовательный <br /> в результате.

Можете ли вы попробовать это, используя рекурсивный CTE?
Может потребоваться замена оператора concat, а также ISNULL но я не был полностью уверен в вашей СУБД ...

WITH OrderedDates AS (
SELECT a.UserID, a.EventID, a.AssignID, a.WaitListed, CONVERT(varchar, d.EventDate, 101)                AS strEventDate,
    ROW_NUMBER() OVER (Partition BY a.UserID, a.EventID, a.AssignID, a.WaitListed ORDER BY d.EventDate) AS EventDateOrder,
    COUNT(*)     OVER (Partition BY a.UserID, a.EventID, a.AssignID, a.WaitListed)                      AS EventDateCount
FROM EventAssignments AS a 
INNER JOIN EventDates AS d ON a.DateID = d.DateID
), ConcatDates AS (
    SELECT UserID, EventID, AssignID, WaitListed, EventDateOrder, EventDateCount, strEventDate
    FROM OrderedDates
    WHERE EventDateOrder = 1
    UNION ALL
    SELECT OD.UserID, OD.EventID, OD.AssignID, OD.WaitListed, OD.EventDateOrder, OD.EventDateCount, CD.strEventDate + '<br />' + OD.strEventDate
    FROM OrderedDates OD
    JOIN ConcatDates CD on OD.UserID = CD.UserID AND OD.EventID = CD.EventID AND OD.AssignID = CD.AssignID AND OD.WaitListed = CD.WaitListed AND OD.EventDateOrder = CD.EventDateOrder + 1
)
SELECT ISNULL(CD1.UserID, CD2.UserID), ISNULL(CD1.EventID, CD2.EventID), ISNULL(CD1.AssignID, CD2.AssignID), CD1.strEventDate, CD2.strEventDate
FROM            (SELECT * FROM ConcatDates WHERE EventDateCOunt = EventDateOrder AND WaitListed = 'false') CD1
FULL OUTER JOIN (SELECT * FROM ConcatDates WHERE EventDateCOunt = EventDateOrder AND WaitListed = 'true' ) CD2 ON CD1.UserID = CD2.UserID AND CD1.EventID = CD2.EventID AND CD1.AssignID = CD2.AssignID
...