Pivot [Transform] таблица по дням месяца по конкретному месяцу и пользователю - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть две таблицы с именами «Записи» и «Пользователи».Структура таблицы выглядит следующим образом.

Таблица [Записи]

Идентификатор, Имя пользователя, IP, Дата
1, Мурат, 192.168.1.100, 2019-02-17 04: 12: 20.470
2, мурат, 192.168.1.100, 2019-02-17 04: 33: 36.120
3, майкл, 192.168.120.175, 2019-02-17 08: 08: 22.210

Пользователи [Пользователи]

Имя пользователя, Имя, Почта, Отдел, Запись, Функция, Уровень, Менеджер, ManagerTop
murat, Murat, murat@asd.com, 11111, ИТ, отдел программного обеспечения, 1, Кобе, Майкл
Майкл, Майкл, michael@asd.com, 22222, ИТ, Служба поддержки, 2, Шак, Майкл

Что я хотел бы сделатьПоверните таблицу [Записи] по дням месяца по определенному месяцу и имени пользователя.

То, что я хочу, выглядит примерно так:

Имя пользователя, Имя, ManagerTop, Менеджер, Месяц, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 2425, 26, 27, 28, 29, 30, 31
Мурат, Мурат, Майкл, Кобе, Февраль, Нет, Нет, Нет, Нет, Нет, Нет, Нет, Нет, Нет, Нет, Нет,No, нет, нет, нет, нет, нет, да , нет, нет, нет, нет, нет, нет, нет, нет, нет, нет, нет, нет, нет, нет, нет, нет

Я ценю вашу поддержку

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Этого можно добиться с помощью Pivot, для этого вам нужно использовать CTE для генерации месяцев и дней, которые вы ищете.Я написал запрос, предполагая, что ваши даты попадают в границы одного года. Если вы хотите продлить до нескольких лет, вы можете легко сделать это, сгенерировав год между минимальной датой и максимальной датой.

declare @table1 table(Id int, Username varchar(100), IP varchar(20), [Date] datetime)
insert into @table1 select 1, 'murat'   , '192.168.1.100', '2019-02-17 04:12:20.470'
insert into @table1 select 2, 'murat'   , '192.168.1.100', '2019-02-17 04:33:36.120'
insert into @table1 select 3, 'michael', '192.168.120.175', '2019-02-17 08:08:22.210'

declare @table2 table( Username varchar(100), Name varchar(100), Mail varchar(100), Department varchar(100), Record varchar(100), [Function] varchar(100), [Level] int , Manager varchar(100), ManagerTop varchar(100))
insert into @table2 select 'murat', 'Murat', 'murat@asd.com', '11111', 'IT', 'Software Department', 1, 'Kobe', 'Michael'
insert into @table2 select 'michael', 'Michael', 'michael@asd.com', '22222', 'IT', 'Helpdesk', 2, 'Shaq', 'Michael'

;WITH cte(months) 
     AS (SELECT 1 
         UNION ALL 
         SELECT months + 1 
         FROM   cte 
         WHERE  months < 31), 
     n(n) 
     AS (SELECT 1 
         UNION ALL 
         SELECT n + 1 
         FROM   n 
         WHERE  n < 31), 
     cte2 
     AS (SELECT C.months AS CM, 
                n.n      AS CD 
         FROM   cte C 
                CROSS JOIN n), 
     cte3 
     AS (SELECT username, 
                NAME, 
                managertop, 
                mname, 
                t2.[date], 
                C2.cd, 
                CASE 
                  WHEN Month(date) = C2.cm 
                       AND Day(date) = cd THEN 'Yes' 
                  ELSE 'No' 
                END Present, 
                rn 
         FROM   cte2 C2 
                INNER JOIN (SELECT [date], 
                                   T1.username, 
                                   T2.NAME, 
                                   T2.managertop, 
                                   Datename(month, Dateadd(month, Month([date]),0)- 1) 
                                   Mname, 
                                   Row_number() 
                                     OVER ( 
                                       partition BY T1.username 
                                       ORDER BY T1.date) 
                                   RN 
                            FROM   @table1 T1 
                                   INNER JOIN @table2 T2 
                                           ON T1.username = T2.username)T2 
                        ON Month(t2.date) = C2.cm) 
SELECT username, 
       NAME, 
       managertop, 
       mname AS [Month], 
       [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31]
FROM   (SELECT * 
        FROM   cte3 
        WHERE  rn = 1) AS SourceTable 
       PIVOT ( Max(present) 
             FOR cd IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31]) ) AS pivottable; 

Онлайн-демонстрация

Вывод

+----------+---------+------------+----------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
| username | NAME    | managertop | Month    | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  | 9  | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17  | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
+----------+---------+------------+----------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
| michael  | Michael | Michael    | February | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No |
+----------+---------+------------+----------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
| murat    | Murat   | Michael    | February | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No |
+----------+---------+------------+----------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
0 голосов
/ 17 февраля 2019

A PIVOT действительно может использоваться для этого.

И таблица «Пользователи» может быть присоединена к сводной таблице.

SELECT 
pvt.Username, 
usr.Name,
usr.ManagerTop, 
usr.Manager,
pvt.[Month], 
IIF([1]>0,'Yes','No') AS [1],
IIF([2]>0,'Yes','No') AS [2],
-- Add the other days
IIF([17]>0,'Yes','No') AS [17],
-- Add the other days
IIF([30]>0,'Yes','No') AS [30],
IIF([31]>0,'Yes','No') AS [31]
FROM
(
   SELECT
   rec.Username,  
   YEAR(rec.[Date]) AS [Year],
   DATENAME(month, rec.[Date]) AS [Month],
   DAY(rec.[Date]) AS [Day]
   FROM [Records] rec
   WHERE rec.[Date] >= DATEFROMPARTS(YEAR(GetDate()), 1, 1)
) src
PIVOT 
(
  COUNT([Day])
  FOR [Day] IN (
     [1],[2],[3],[4],[5],[6],[7],[8],
     [9],[10],[11],[12],[13],[14],[15],[16],
     [17],[18],[19],[20],[21],[22],[23],[24],
     [25],[26],[27],[28],[29],[30],[31])
) pvt
LEFT JOIN [Users] usr 
     ON usr.Username = pvt.Username
ORDER BY pvt.Username;

Тест на rextester здесь

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