Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите вычислить промежуток времени между двумя записями в базе [D7, MSSQL]


Страницы:   1 2

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 человек на предприятии

Кстати, не забывайте и такой факт:
допустим нужно получить табель сотрудников за вчера. А кто-то в ночную смену работал. Т.е. первое событие за этот день в системе у него - ВЫХОД.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо