![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите вычислить промежуток времени между двумя записями в базе [D7, MSSQL]
Sens © (2004-04-13 08:34:00)Помогите!!! Работаю над программой отчетов по электронным проходным, не знаю как сделать учет рабочего времени за день (хотябы за день). Когда человек проходит через проходные в базе регистрируется его номер направление и время прохода, за день таких регистраций может быть очень много (если например человек бегает по вызовам), а мне нужно получить сумму времени, которую человек провел в центральном здании, или хотябы время между первой (входной) и последней (выходной) регистрацией человека. Пока не знаю как запрос организовать, и при этом, чтобы он выполнялся быстро. Если есть идеи - помогите.
sniknik (2004-04-13 12:54:00) [1]> Arithmetic overflow error converting expression to data type datetime.
кстати возможно не к тому преобразованию относится где float а к
between '01.03.2004' AND '02.03.2004'
этому
задавай параметрами, в крайнеи случае так
between '20040201' AND '20040302'
Sens (2004-04-13 12:51:00) [2]Johnmen © (13.04.04 12:48) [35]
Так правильнее... оказывается у меня по асфальту лыжи не едут...
:)))
SELECT
colAccountNumber,
SUM(datetimediff)
FROM
(SELECT
T1.colAccountNumber,
MIN(CAST(T2.colRegistrationTime-T1.colRegistrationTime AS FLOAT)) AS datetimediff
FROM dbo.tblAllRegistrations T1
JOIN dbo.tblAllRegistrations T2 ON (T2.colAccountNumber=T1.colAccountNumber) AND
(T1.colZoneTarget=1) AND (T2.colZoneTarget=0) AND
(T1.colRegistrationTime<=T2.colRegistrationTime)
GROUP BY T1.colAccountNumber, T1.colRegistrationTime
) AS T
GROUP BY colAccountNumber
Johnmen (2004-04-13 12:48:00) [3]Table в примере - это твоя таблица...
:)
sniknik (2004-04-13 12:46:00) [4]> Arithmetic overflow error converting expression to data type datetime.
попробуй не к float а к real приводить. унего разрядность больше.
Sens (2004-04-13 12:45:00) [5]2 Johnmen © (13.04.04 12:35) [31]
как результат:
===================================
Server: Msg 156, Level 15, State 1, Line 8
Incorrect syntax near the keyword 'Table'.
===================================
Sens (2004-04-13 12:44:00) [6]2 Johnmen © (13.04.04 12:35) [31]
Пробовал, но у меня что-то страшное получилось. Не могу понять, как можно таблицу саму с собой связать.
SELECT
colAccountNumber,
SUM(datetimediff)
FROM
(SELECT
dbo.tblAllRegistrations.colAccountNumber,
MIN(CAST(dbo.tblAllRegistrations.colRegistrationTime-dbo.tblAllRegistrations.colRegistrationTime AS FLOAT)) AS datetimediff
FROM Table dbo.tblAllRegistrations
JOIN Table dbo.tblAllRegistrations ON (dbo.tblAllRegistrations.colAccountNumber=dbo.tblAllRegistrations.colAccountNumber) AND
(dbo.tblAllRegistrations.colZoneTarget=1) AND (dbo.tblAllRegistrations.colZoneTarget=0) AND
(dbo.tblAllRegistrations.colRegistrationTime<=dbo.tblAllRegistrations.colRegistrationTime)
GROUP BY dbo.tblAllRegistrations.colAccountNumber, dbo.tblAllRegistrations.colRegistrationTime
) AS T
GROUP BY dbo.tblAllRegistrations.colAccountNumber
Johnmen (2004-04-13 12:35:00) [7]А чем не устроил [19] ?
Sens (2004-04-13 12:29:00) [8]sniknik © (13.04.04 12:06) [28]
Хотя принцип ясен, думаю разберусь. Спасибо.
Sens (2004-04-13 12:23:00) [9]Что-то у меня опять не как у людей 8-(
Или я тупой или лыжи не едут!
SELECT
CAST(SUM(CASE dbo.tblAllRegistrations.colAccountNumber
WHEN 1144
THEN -CAST(dbo.tblAllRegistrations.colRegistrationTime AS FLOAT)
ELSE CAST(dbo.tblAllRegistrations.colRegistrationTime AS FLOAT) END) AS DateTime)
FROM dbo.tblAllRegistrations
Where
dbo.tblAllRegistrations.colRegistrationTime between '01.03.2004' AND '02.03.2004'
============================================================
Server: Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type datetime.
=============================================================
sniknik (2004-04-13 12:06:00) [10]да 1 у меня это похоже 1144 у тебя, и дата будет
01.01.1900 8:54:19
вместо
30.12.1899 8:54:19
но это все одно ноль ;о))
sniknik (2004-04-13 12:02:00) [11]для MSSQL
SELECT
CAST(SUM(CASE AcNum WHEN 1 THEN -CAST(RegTime AS FLOAT) ELSE CAST(RegTime AS FLOAT) END) AS DateTime)
FROM Table2
sniknik (2004-04-13 11:49:00) [12]Sens © (13.04.04 11:45) [24]
это для аксеса, для mssql будет по другому (первый вариант что приводил), счас проверю точнее (может там вообще не пойдет (не верю ;о)).
Delirium (2004-04-13 11:48:00) [13]MSSQL не знает что такое iif
Sens (2004-04-13 11:45:00) [14]2 sniknik
Подправь пожалуйста, где-то я проглючил
SELECT CDate(SUM(iif(tblAllRegistrations.colAccountNumber =1144,-1,1)*colRegistrationTime)) FROM dbo.tblAllRegistrations
-------------------------------------------
Server: Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near '='.
-------------------------------------------
Anatoly Podgoretsky (2004-04-13 11:28:00) [15]Ega23 © (13.04.04 10:53) [18]
Не забываю, день минус 1 и анализ на отсутствия выхода (с временем более последнего входа) в этот день. Там уже варианты относить в предудущему месяцу, к текущему или разбить по обеим месяцам пропорционально. Другой вариант, входа нет, считать за первое число и время 0.
Delirium (2004-04-13 11:12:00) [16]Кстати, потестировав, могу сказать, что вышеозначеный индекс на больших объёмах даёт выигрыш более чем в 60 раз.
create unique clustered index #ix on #t (C asc)
Delirium (2004-04-13 11:04:00) [17]Ещё вариант быстрого совмещения времен, поле A - вход/выход, поле B - время, на поле С во временной таблице рекомендую наложить кластерный индекс
select *,
Identity(int, 1, 1) as C
into #t
from t
order by B
select *
from #t t1
join #t t0 on t1.C=t0.C-1
where (t1.A=1) and (t0.A=0)
sniknik (2004-04-13 10:59:00) [18]проверил (правда в access) идею в [4] по данным в Sens © (13.04.04 09:15) [6]
(просто для примера)
ничего, работает
SELECT CDate(SUM(iif(client_id =1,-1,1)*servicedate)) FROM Table2
результат
30.12.1899 8:54:19
ну 30.12.1899 это ноль, а время на работе -> 8:54:19, кстати переработка!! ;о)
(таблицу взял первую попавшуюся, т.е. названия полей мои)
Johnmen (2004-04-13 10:54:00) [19]>Sens ©
Можно запросом :
SELECT
colAccountNumber,
SUM(datetimediff)
FROM
(SELECT
T1.colAccountNumber,
MIN(CAST(T2.colRegistrationTime-T1.colRegistrationTime AS FLOAT)) AS datetimediff
FROM Table T1
JOIN Table T2 ON (T2.colAccountNumber=T1.colAccountNumber) AND
(T1.colZoneTarget=1) AND (T2.colZoneTarget=0) AND
(T1.colRegistrationTime<=T2.colRegistrationTime)
GROUP BY T1.colAccountNumber, T1.colRegistrationTime
) AS T
GROUP BY colAccountNumber
Ega23 (2004-04-13 10:53:00) [20]Anatoly Podgoretsky © (13.04.04 10:44) [17]
Если не 5000 человек на предприятии
Кстати, не забывайте и такой факт:
допустим нужно получить табель сотрудников за вчера. А кто-то в ночную смену работал. Т.е. первое событие за этот день в системе у него - ВЫХОД.