У меня есть таблица, в которой есть записи о работах, ведущих к входным дверям.
DECLARE @doorStatistics TABLE
( id INT IDENTITY,
[user] VARCHAR(250),
accessDate DATETIME,
accessType VARCHAR(5)
)
Пример записи:
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('John Wayne','2009-09-01 07:02:43.000','IN')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('Bruce Willis','2009-09-01 07:12:43.000','IN')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('Bruce Willis','2009-09-01 07:22:43.000','OUT')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('John Wayne','2009-09-01 07:32:43.000','OUT')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('John Wayne','2009-09-01 07:37:43.000','IN')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('Bruce Willis','2009-09-01 07:42:43.000','IN')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('John Wayne','2009-09-01 07:48:43.000','OUT')
INSERT INTO @doorStatistics([user],accessDate,accessType) VALUES ('Bruce Willis','2009-09-01 07:52:43.000','OUT')
То, что я хочу сделать, это запрос, который дает мне следующий результат (на основе приведенного выше примера):
| user | date | inHour | outHour |
|--------------|------------|----------|----------|
| John Wayne | 2009-09-01 | 07:02:43 | 07:48:43 |
| Bruce Willis | 2009-09-01 | 07:12:43 | 07:22:43 |
| John Wayne | 2009-09-02 | 07:37:43 | 07:48:43 |
| Bruce Willis | 2009-09-02 | 07:42:43 | 07:52:43 |
Я сделал следующий запрос:
SELECT [user], accessDate AS [in date],
(SELECT MIN(accessDate)
FROM @doorStatistics ds2
WHERE accessType = 'OUT'
AND ds2.accessDate > ds.accessDate
AND ds.[user] = ds2.[user]) AS [out date]
FROM @doorStatistics ds
WHERE accessType = 'IN'
Но это нехорошо, потому что когда пользователь забудет зарегистрировать свой вход, он выдаст, например, что-то вроде этого:
| user | date | inHour | outHour |
|--------------|------------|----------|----------|
| John Wayne | 2009-09-02 | 07:02:43 | 07:48:43 |
| John Wayne | 2009-09-02 | 07:02:43 | 09:26:43 |
Пока должно быть
| user | date | inHour | outHour |
|--------------|------------|----------|----------|
| John Wayne | 2009-09-02 | 07:02:43 | 07:48:43 |
| John Wayne | 2009-09-02 | NULL | 09:26:43 |
Вторая причина, по которой запрос не является хорошим, - это производительность. У меня более 200 000 записей, и SELECT для каждой строки замедляет запрос.
Возможным решением может быть объединение двух таблиц
SELECT * FROM @doorStatistics WHERE accessType = 'IN'
с
SELECT * FROM @doorStatistics WHERE accessType = 'OUT'
но я понятия не имею, какие условия поставить, чтобы получить правильную дату. Может быть, там можно поставить некоторые функции MAX или MIN, но я понятия не имею.
Я не хочу создавать временную таблицу и использовать курсоры.