Заполнение столбцов пути xml

    Declare @SQL varchar(max) = 'Select NOM_EMP as [X],PRENOM_EMP as [Y],'
+ (Select Stuff((Select ',[' +cast(N as varchar(25))+']=''''' 
                From (Select Top (31) N=Row_Number() Over (Order By (Select null)) From master..spt_values n1) A
                For XML Path 
                (''))
                ,1,1,'')
   )
+ ' FROM EMPLOYE'

Exec(@SQL)

Я загружаю имена сотрудников + количество дней в текущем месяце (в данном случае 31). Вышеупомянутый запрос приведет к примерно такому результату:

enter image description here

Таблица сотрудников связана с (EMPLOYE_ID), скажем, с таблицей Requests, каждый запрос имеет start_date и end_date.

Я хочу добиться того, чтобы буква «R» была написана, если номер дня start_date и end_date совпадает с номером дня в ячейке.

Если запрос сделан (первым сотрудником) с такой информацией: 08-10-2018 и 14.08.2018

Таблица должна выглядеть так:

enter image description here

Реально ли этого достичь? Если да, то любая помощь приветствуется.

Обновлено:

    Declare @D1 datetime = '2018-08-01'
Declare @D2 datetime = '2018-08-31'


Declare @Cols varchar(max) = (Select Stuff((Select ',[' +cast(N as varchar(25))+']' From (Select Top (DateDiff(DAY,@D1,@D2)+1) N=Row_Number() Over (Order By (Select Null)) From  master..spt_values n1) A For XML Path ('')),1,1,'') )
Declare @SQL varchar(max) = '
Declare @D1 date = '''+cast(@D1 as varchar(50))+'''
Declare @D2 date = '''+cast(@D2 as varchar(50))+'''

Select *
 From  ( 
        Select firstName,LastName,
              Item      = day(d)
              ,Value     = case when D between DEBUT_DRC and FIN_DRC then ''R'' else '''' end
         From DEMANDE_RECUPERATION DC INNER JOIN EMPLOYE E ON DC.MAT_EMP = E.MAT_EMP 
         Cross Join (
                        Select Top (DateDiff(DAY,@D1,@D2)+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@D1) From  master..spt_values n1
                    ) B
       ) src
 Pivot (max(value) for Item in ('+@Cols+') ) pvt
'
Exec(@SQL)

Выход:

enter image description here

2
0
136
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Просто немного расширив свой динамический SQL

Пример

Declare @D1 date = '2018-08-01'
Declare @D2 date = '2018-08-31'


Declare @Cols varchar(max) = (Select Stuff((Select ',[' +cast(N as varchar(25))+']' From (Select Top (DateDiff(DAY,@D1,@D2)+1) N=Row_Number() Over (Order By (Select Null)) From  master..spt_values n1) A For XML Path ('')),1,1,'') )
Declare @SQL varchar(max) = '
Declare @D1 date = '''+cast(@D1 as varchar(50))+'''
Declare @D2 date = '''+cast(@D2 as varchar(50))+'''

Select *
 From  ( 
        Select A.Employee
              ,Item      = day(d)
              ,Value     = case when D between start_date and end_date then ''R'' else '''' end
         From YourRequestTable A
         Cross Join (
                        Select Top (DateDiff(DAY,@D1,@D2)+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@D1) From  master..spt_values n1
                    ) B
       ) src
 Pivot (max(value) for Item in ('+@Cols+') ) pvt
'
Exec(@SQL)

Возврат

enter image description here

Он ничего не возвращает. Сначала я подумал, что это мое внутреннее соединение, но я попытался получить EmployeID, поскольку у меня есть имена в другой таблице, но это ничего не дало. Он по-прежнему возвращает пустую таблицу

Zkai 11.08.2018 09:37

@Zkai Вы никогда не публиковали свои фактические структуры, но вот dbfiddle dbfiddle.uk/…

John Cappelletti 11.08.2018 12:32

Я выложил свои работы. Ошибок не возвращается, а возвращаемая таблица пуста. Возможно ли это, потому что я использую Datetime вместо date? но я в этом сомневаюсь.

Zkai 11.08.2018 14:46

@Zkai для начала, переменные D1 и D2 datetime должны быть DATE, а не datetime. Если вы запустите подзапрос "src", получите ли вы данные ... вам нужно будет объявить переменные D1 и D2

John Cappelletti 11.08.2018 14:56

@Zkai Вместо Exec ({at} SQL) Print {at} SQL будет создан сгенерированный SQL. Возможно, это раскроет проблему. Я подозреваю, что ты присоединился

John Cappelletti 11.08.2018 14:59

Забудь. Я выполнял запрос в базе данных "Master", я забыл выбрать свою базу данных, и поэтому он ничего не возвращал.

Zkai 11.08.2018 15:11

@Zkai Это всегда мелочи :)

John Cappelletti 11.08.2018 15:12

Верно. Кстати, спасибо, что нашли время и ответили мне, я ценю это :)

Zkai 11.08.2018 15:13

более менее:

WITH cteDates AS ( SELECT [calDt] = @dtStart
                   UNION ALL
                   SELECT [CalDt] = DATEADD(DAY, [calDt], 1) FROM cteDates WHERE [calDt] <= @dtEnd)
SELECT pvt.*
  FROM ( SELECT e.EmployeeID, d.[calDt], [reqCount] = COUNT(*)
           FROM cteDates d
          CROSS JOIN Employee e
           LEFT JOIN reqTable rt ON rt.EmployeeID = e.EmployeeID
                                AND rt.d1 >= d.[cteDt]
                                AND rt.d2 <= d.[cteDt]
         GROUP BY e.EmployeeID, d.[calDt]
       ) unpvt
 PIVOT ( SUM(reqCount) FOR [calDt] IN ( [1],[2],...[31] )
       ) AS pvt

не требуется динамический SQL

Другие вопросы по теме