2011-03-03 6 views
1

EntryTime과 ExitTime의 차이를 가져 오는 데 문제가 있습니다. IOData라는 테이블이 있고 IOTime 열에서 작업하고 있습니다. 테이블의 형식은 다음과 같습니다entryTime과 exitTime의 차이점을 MS Access 데이터베이스에서 찾으십시오.

 
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를 2 열 (시작 및 종료)으로 나누면 상태 항목이 작을 수도 있고 끝날 수도 있습니다. 제안 사항을 보내 주시면 감사하겠습니다.
미리 감사드립니다.

+1

우선 IODate와 IOTime을 단일 IODateTime 필드에 결합해야합니다. 날짜와 시간을 두 개의 열로 나누어 불필요하게 더 어렵게 만들었습니다. 제트 엔진은 시간을 나타내는 십진수로 float 형으로 datetimes를 저장합니다. 하루 이상의 시간 차이를 계산하는 것은 현재 설정에서 악몽이 될 것입니다. – mwolfe02

답변

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"형식으로 표시합니다. 나는 첫 번째 행에 대한 null 타임 스탬프를 무시합니다.

+0

Asker가 ms 액세스로 태그를 지정했습니다. 나는 당신이 TSQL을 여기에 작성했다고 추측하고 있는데, 그것은 jet SQL 에서처럼 실행되지 않을 것이다. – mwolfe02

+0

이전 예제는 TSQL이 아닌 표준 SQL입니다. 일반적으로 유용하기 때문에, 그리고 입력하는 데 시간이 걸리기 때문에 나는 그것을 떠날 것이다. –

+0

+1 직접 테스트하지 않으면 작동하는 것처럼 보입니다. 물론 Asker가 db 스키마를 제어하고 날짜와 시간 열을 결합 할 수 있다면 훨씬 간단한 쿼리 일 것입니다. – mwolfe02

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를 수행해야합니다. 또한 중첩 된 위치가 가능한 경우 중첩 된 위치를 처리해야 할 수도 있습니다 (예 : 실험실 내부의 클린 룸, 실험실 자체의 출입구 이벤트 사이에 클린 룸의 출입구가 있음).

이러한 모든 사항은이 디자인으로 처리 할 수 ​​있으며보고가 크게 단순 해지고 효율적입니다.

위치에 소요 된 시간에 대한 원래 질문에 대답하는 것이 쉽습니다.

+0

이것은 정규화와는 아무런 관련이 없습니다. 원래 데이터는 5NF입니다. 당신의 생각은 사람이 같은 문으로 들어갔다 나오는 것을 전제로합니다. 현실 세계에서는 이것이 사실로 신뢰할 수 없으며 제공된 샘플 데이터조차 사실이 아닙니다. (04:11:54에 시작하는 항목을보십시오.) –

+0

그러면 묻는 사람이 원하는 것을 혼란스럽게 생각합니다. 04:11 지하실 입구의 경우 해당 출구 기록은 무엇입니까? 그가 05:10에 1 층에 입장 할 때 암시 된 지하실 출구가 있다고 주장 할 수 있습니다. 내 스키마는이 경우를 쉽게 지원합니다. – mwolfe02

+0

@Catcall : 질문에서 Asker는 EntryTime과 ExitTime의 차이점에 대해 구체적으로 질문했습니다. 솔루션에서 제공하는 것은 연속 이벤트 간의 경과 시간입니다. 묻는 사람이 당신의 해결책을 받아 들였기 때문에 이것은 묻는 사람이 실제로 원하는 것 같지만 그가 요구 한 것 같지 않습니다. – mwolfe02

관련 문제