我在检索EntryTime和ExitTime之间的区别时遇到了问题。我有一个名为IOData的表,我正在研究IOTime列。 该表的格式为:
HolderName IODate IOTime IOGateName IOStatus Dinesh Kumar 2010/07/09 00:50:05 Basement(I/O) Entry Dinesh Kumar 2010/07/09 00:52:55 Basement(I/O) Exit Dinesh Kumar 2010/07/09 01:00:07 Basement(I/O) Entry Dinesh Kumar 2010/07/09 01:35:42 Basement(I/O) Exit Dinesh Kumar 2010/07/09 01:36:37 Ground Floor(I/O) Entry Dinesh Kumar 2010/07/09 01:37:02 Ground Floor(I/O) Exit Dinesh Kumar 2010/07/09 01:46:04 Ground Floor(I/O) Entry Dinesh Kumar 2010/07/09 01:46:29 Ground Floor(I/O) Exit Dinesh Kumar 2010/07/09 01:47:02 Basement(I/O) Entry Dinesh Kumar 2010/07/09 04:09:11 Basement(I/O) Exit Dinesh Kumar 2010/07/09 04:09:35 Ground Floor(I/O) Entry Dinesh Kumar 2010/07/09 04:11:27 Ground Floor(I/O) Exit Dinesh Kumar 2010/07/09 04:11:54 Basement(I/O) Entry Dinesh Kumar 2010/07/09 05:10:28 Ground Floor(I/O) Entry Dinesh Kumar 2010/07/09 05:18:12 Main Door(I/O) Exit Dinesh Kumar 2010/07/09 17:55:16 Main Door(I/O) Entry Dinesh Kumar 2010/07/09 17:56:10 Ground Floor(I/O) Entry
问题是我有一列用于区分时间。我怎样才能克服这个问题。 如果我在两列(进入和退出)中打破IOStatus,那么状态输入可以小于退出或副指令 任何建议将不胜感激 提前致谢
答案 0 :(得分:1)
我会创建一个视图。
create view suspicious_person_movements as
select IO.holder_name,
cast(IO.io_date || ' ' || IO.io_time as timestamp) as io_timestamp,
-- Concatenate most recent earlier date and time, and cast to timestamp
cast((select max(io_date)
from iodata
where holder_name = IO.holder_name
and io_date <= IO.io_date)
|| ' ' ||
(select max(io_time)
from iodata
where holder_name = IO.holder_name
and io_date <= IO.io_date
and io_time < IO.io_time) as timestamp) as previous_timestamp,
-- Subtract the timestamps to get elapsed_time
cast(IO.io_date || ' ' || IO.io_time as timestamp) -
cast((select max(io_date)
from iodata
where holder_name = IO.holder_name
and io_date <= IO.io_date) || ' ' ||
(select max(io_time)
from iodata
where holder_name = IO.holder_name
and io_date <= IO.io_date
and io_time < IO.io_time) as timestamp) as elapsed_time,
IO.io_gate_name,
IO.io_status
from iodata IO
order by holder_name, io_date, io_time -- Better to sort in the client?
然后我可以从suspicious_person_movements中选择所有行。 (轻微编辑以减少水平滚动。)
Dinesh 2010-07-09 00:50:05 Basement(I/O) Entry
Dinesh 2010-07-09 00:52:55 2010-07-09 00:50:05 00:02:50 Basement(I/O) Exit
Dinesh 2010-07-09 01:00:07 2010-07-09 00:52:55 00:07:12 Basement(I/O) Entry
Dinesh 2010-07-09 01:35:42 2010-07-09 01:00:07 00:35:35 Basement(I/O) Exit
Dinesh 2010-07-09 01:36:37 2010-07-09 01:35:42 00:00:55 Ground Fl(I/O) Entry
Dinesh 2010-07-09 01:37:02 2010-07-09 01:36:37 00:00:25 Ground Fl(I/O) Exit
Dinesh 2010-07-09 01:46:04 2010-07-09 01:37:02 00:09:02 Ground Fl(I/O) Entry
Dinesh 2010-07-09 01:46:29 2010-07-09 01:46:04 00:00:25 Ground Fl(I/O) Exit
Dinesh 2010-07-09 01:47:02 2010-07-09 01:46:29 00:00:33 Basement(I/O) Entry
Dinesh 2010-07-09 04:09:11 2010-07-09 01:47:02 02:22:09 Basement(I/O) Exit
Dinesh 2010-07-09 04:09:35 2010-07-09 04:09:11 00:00:24 Ground Fl(I/O) Entry
Dinesh 2010-07-09 04:11:27 2010-07-09 04:09:35 00:01:52 Ground Fl(I/O) Exit
Dinesh 2010-07-09 04:11:54 2010-07-09 04:11:27 00:00:27 Basement(I/O) Entry
Dinesh 2010-07-09 05:10:28 2010-07-09 04:11:54 00:58:34 Ground Fl(I/O) Entry
Dinesh 2010-07-09 05:18:12 2010-07-09 05:10:28 00:07:44 Main Door(I/O) Exit
Dinesh 2010-07-09 17:55:16 2010-07-09 05:18:12 12:37:04 Main Door(I/O) Entry
Dinesh 2010-07-09 17:56:10 2010-07-09 17:55:16 00:00:54 Ground Fl(I/O) Entry
我以最明显的方式实现了视图。您需要持有者姓名,日期和时间的索引。通过将表连接到自身而不是使用这些标量子查询,可以获得更好的性能。无论哪种方式,大型数据集的性能可能都不是很好。 (但您通常可以限制持有人姓名和日期范围,这将有所帮助。)
对于Access,您将使用更像这样的查询,我从SQL视图中复制。
SELECT IO.holder_name
, [io_date] & " " & [io_time] AS io_timestamp
, (select max(io_date)
from iodata
where holder_name = IO.holder_name
and io_date <= IO.io_date)
& " " &
(select max(io_time)
from iodata
where holder_name = IO.holder_name
and io_date <= IO.io_date
and io_time < IO.io_time) AS previous_timestamp
, DateDiff("n",[previous_timestamp],[io_timestamp]) AS elapsed_minutes
, IO.io_gate_name
, IO.io_status
FROM iodata AS IO
ORDER BY IO.holder_name, IO.io_date, IO.io_time;
我采取了一些捷径,因为我在工作。我以“00:00:00”格式显示经过的分钟而不是经过的时间。我忽略第一行的空时间戳。
答案 1 :(得分:1)
如果可能的话(我意识到这可能为时已晚),我建议您重新设计您的架构。以下似乎更有意义:
HolderName IOGateName EnterDT ExitDT Dinesh Kumar Basement(I/O) 2010/07/09 00:50:05 2010/07/09 00:52:55 Dinesh Kumar Basement(I/O) 2010/07/09 01:00:07 2010/07/09 01:35:42 Dinesh Kumar Ground Floor(I/O) 2010/07/09 01:36:37 2010/07/09 01:37:02
请注意,虽然它看起来可能看起来像数据较少,但实际上并没有丢失任何信息...只是规范化您的结构。
在数据输入方面需要一些小心。例如,除了INSERT之外,您还需要执行UPDATE。如果可能的话,您可能需要处理嵌套位置(例如,实验室内的洁净室,洁净室的入口/出口将介于实验室本身的进入和退出事件之间)。
所有这些事情仍然可以通过这种设计来处理,报告将大大简化并提高效率。
回答关于在某个地点花费的时间的原始问题现在很简单。