Возврат нескольких строк из значения столбца

Мне нужно создать XML из моей хранимой процедуры. В моей базе данных есть несколько значений, хранящихся в одной строке, например:

ScheduleID      EmployeeID  M   Tu  W   Th  F   Sa  Su
======================================================
10              10001       1   1   0   0   0   0   0
11              10001       0   0   0   1   0   0   0
12              10002       0   0   0   0   0   1   1

Мне нужно создать XML, который будет выглядеть следующим образом:

<schedules>
  <task>
    <ScheduleID>10</ScheduleID>
    <EmployeeID>10001</EmployeeID>
    <Workday>Monday</Workday>
  </task>
  <task>
    <ScheduleID>10</ScheduleID>
    <EmployeeID>10001</EmployeeID>
    <Workday>Tuesday</Workday>
  </task>
    <task>
    <ScheduleID>11</ScheduleID>
    <EmployeeID>10001</EmployeeID>
    <Workday>Thursday</Workday>
  </task>
  <task>
    <ScheduleID>12</ScheduleID>
    <EmployeeID>10002</EmployeeID>
    <Workday>Saturday</Workday>
  </task>
  <task>
    <ScheduleID>12</ScheduleID>
    <EmployeeID>10002</EmployeeID>
    <Workday>Sunday</Workday>
  </task>
</schedules>

Проблема, с которой я сталкиваюсь, заключается в том, что для выполнения вышеизложенного мне нужно будет возвращать разные строки для каждого дня недели. Поэтому я подумал об использовании оператора case, однако ближе всего я пришел к следующему, которое не сработало бы, так как создает несколько столбцов с именем "Workday". Поскольку для каждого ScheduleID может быть допустимо любое время от 1 до 7 дней, добавление ELSE также не будет возможным. Как я могу сделать это?

SELECT ScheduleID, EmployeeID,
    CASE WHEN (M = 1) THEN 'Monday' END as Workday,
    CASE WHEN (Tu = 1) THEN 'Tuesday' END as Workday,
    CASE WHEN (W = 1) THEN 1 ELSE 0 END as Workday,
    CASE WHEN (Th = 1) THEN 1 ELSE 0 END as Workday,
    CASE WHEN (F = 1) THEN 1 ELSE 0 END as Workday,
    CASE WHEN (Sa = 1) THEN 1 ELSE 0 END as Workday,
    CASE WHEN (Su = 1) THEN 1 ELSE 0 END as Workday
FROM Schedules
FOR XML PATH('task'), ROOT('schedules')

1 ответ

Решение

Тестовые данные

DECLARE @T TABLE (ScheduleID INT, EmployeeID INT ,  M INT, 
                  Tu INT, W INT,  Th INT, F INT,  Sa INT, Su INT)
INSERT INTO @T VALUES 
(10 ,10001  ,1 ,  1 ,  0 ,  0 ,  0 ,  0 ,  0),
(11 ,10001  ,0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0),
(12 ,10002  ,0 ,  0 ,  0 ,  0 ,  0 ,  1 ,  1)

запрос

;WITH X AS 
 (
SELECT *
 FROM (
    SELECT ScheduleID
          ,EmployeeID
          ,NULLIF(M , 0) AS Monday
          ,NULLIF(Tu, 0) AS Tuesday
          ,NULLIF(W , 0) AS Wednesday
          ,NULLIF(Th, 0) AS Thursday
          ,NULLIF(F , 0) AS Friday
          ,NULLIF(Sa, 0) AS Saturday
          ,NULLIF(Su, 0) AS Sunday
    FROM @T
    )t 
 UNPIVOT (Vals FOR Workday IN (Monday,Tuesday,Wednesday,Thursday
                                                    ,Friday,Saturday,Sunday))up
  )
SELECT ScheduleID
      ,EmployeeID
      ,Workday
FROM X 
FOR XML PATH('task'), ROOT('schedules')

Результат:

<schedules>
  <task>
    <ScheduleID>10</ScheduleID>
    <EmployeeID>10001</EmployeeID>
    <Workday>Monday</Workday>
  </task>
  <task>
    <ScheduleID>10</ScheduleID>
    <EmployeeID>10001</EmployeeID>
    <Workday>Tuesday</Workday>
  </task>
  <task>
    <ScheduleID>11</ScheduleID>
    <EmployeeID>10001</EmployeeID>
    <Workday>Thursday</Workday>
  </task>
  <task>
    <ScheduleID>12</ScheduleID>
    <EmployeeID>10002</EmployeeID>
    <Workday>Saturday</Workday>
  </task>
  <task>
    <ScheduleID>12</ScheduleID>
    <EmployeeID>10002</EmployeeID>
    <Workday>Sunday</Workday>
  </task>
</schedules>
Другие вопросы по тегам