Сохранять результаты запроса в переменной в SQL Server - PullRequest
0 голосов
/ 22 октября 2018

У меня есть следующие данные:

CREATE TABLE TimeLog 
(
     [User] NVARCHAR(6),
     [Event] NVARCHAR(3),
     [Time] DATETIME
);

INSERT INTO TimeLog 
VALUES (N'Mark', N'IN', '2015-04-15 00:31:00'),
       (N'Mark', N'IN', '2015-04-16 20:10:00'),
       (N'Mark', N'IN', '2015-04-21 14:59:00'),
       (N'Mark', N'OUT', '2015-04-22 01:01:00'),
       (N'Mark', N'IN', '2015-04-22 10:46:00'),
       (N'Mark', N'OUT', '2015-04-23 00:58:00'),
       (N'Mark', N'IN', '2015-04-23 14:50:00'),
       (N'Mark', N'OUT', '2015-04-24 01:37:00'),
       (N'Mark', N'OUT', '2015-04-25 01:01:00'),
       (N'Mark', N'OUT', '2015-04-27 00:57:00'),
       (N'Mark', N'IN', '2015-04-17 10:32:00'),

Я разделил входы и выходы в другой столбец с запросом:

SELECT 
    [UserName], [IN], [OUT] 
FROM
    (SELECT 
         ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) + ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) % 2 AS [PairID],
         *
     FROM  
         [dbo].[AttendanceEvents] 
     WHERE
         UserName = 'Mark') DS
PIVOT
    (MAX([EventTime]) 
        FOR [EventName] IN ([IN], [OUT])
    ) PVT
ORDER BY 
    [PairID];

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

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Самое простое решение - сделать это на лету:

SELECT [UserName]
  ,AVG(DATEDIFF(minute,[OUT],[IN])) AvgMinutes 

FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) + ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) % 2 AS [PairID]
      ,*
FROM [dbo].[AttendanceEvents] Where UserName = 'Mark'
) DS
PIVOT
(
MAX([EventTime]) FOR [EventName] IN ([IN], [OUT])
) PVT
GROUP BY [UserName];

Но если вы хотите вставить его во что-то, используйте insert.

Что-то может быть локальной временной таблицей, глобальной временной таблицей или табличной переменной.

Или вы можете использовать ранее упомянутый подход CTE.

Вот пример.Вы должны использовать соответствующие типы данных.Я просто использовал VARCHAR

Я удаляю order by, потому что данные никогда не вставляются ни в каком порядке - только когда вы выбираете их обратно.

DECLARE @MyTableVariable TABLE (
    Username VARCHAR(50),
    In DATETIME,
    Out DATETIME
)

INSERT INTO @MyTableVariable (UserName, In, Out)
SELECT [UserName]
  ,[IN]
  ,[OUT] 
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) + ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) % 2 AS [PairID]
      ,*
FROM [dbo].[AttendanceEvents] Where UserName = 'Mark'
) DS
PIVOT
(
MAX([EventTime]) FOR [EventName] IN ([IN], [OUT])
) PVT;
0 голосов
/ 22 октября 2018

Вы можете просто определить CTE, а затем запросить:

WITH cte AS (
    SELECT [UserName], [IN], [OUT] 
    FROM
    (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) +
          ROW_NUMBER() OVER (PARTITION BY [UserName] ORDER BY [EventTime]) % 2 AS [PairID]
        FROM [dbo].[AttendanceEvents]
        WHERE UserName = 'Mark'
        ) DS
        PIVOT
        (
            MAX([EventTime]) FOR [EventName] IN ([IN], [OUT])
        ) PVT
    ) t
)

SELECT AVG([IN]) AS avg_in, AVG([OUT]) AS avg_out
FROM cte;
...