2017-05-09 3 views
0

값을 모두 가진 SYSDATE을 맞춰야하지만,이값으로 SYSDATE가있는 두 개의 테이블의 두 열, 나는 두 개의 열을 비교해야

select count(*) from (
     (select col from tab1) 
     minus 
     (select col from tab2)) -- 

1을 제공하지만, 나는 그것이 0이 될 것으로 예상하는 방법

나를 더 명확히하자

create table tab1 (col date) 
-- Can the datatype of `col` be something else 
-- rather than `date` so that when `SYSDATE` 
-- gets inserted to it, I get only `10-MAY-17` 
-- rather than the date along with time? 
-- I have control on this create statement, 
-- I can create the table as I wish to. 

insert into tab1 values (sysdate) 
-- I have no control on this, 
-- this is system generated . 

create table tab2 (col date) 
-- I have control on it. 
-- I can modify it. 

insert into tab2(col) values (sysdate) 
-- I have control on it to change it 

이 문제는 아직 명확하지 않다 있으면 알려 주시기 바랍니다. 감사합니다.

+0

어떤 SQL 백엔드를 사용하고 있습니까? 모든 SQL 구현이 MINUS 연산자를 지원하는 것은 아닙니다. 오라클은 알고 있지만 SQL Server, PostgreSQL 및 SQLite는 EXCEPT 연산자를 사용합니다. – ShaneNal

+0

당신은 분명하지 않습니다. 데이터 유형은 무엇과 관련이 있습니까? 다행히도 두 열에 DATE 데이터 유형이 있으므로 변경해서는 안됩니다. 여기서 문제는 무엇입니까? SYSDATE가 tab1에 삽입되고 동일한 값이 tab2에 삽입되어야하지만 SYSDATE가 나중에 초로 호출되기 때문에 다르다. tab2에서 SYSDATE를 삽입하지 마십시오. tab1의 값을 삽입하십시오. – mathguy

+0

@ShaneNal - OP가 게시물에 잘못 태그를 추가했다고 생각하는 특별한 이유가 있습니까? 필자는 Oracle과 PLSQL을 볼 수 있으며 SYSDATE라는 이름은 오라클에만 한정됩니다. 왜 의심 스럽습니까? – mathguy

답변

-1

sysdate에 대한 것은 현재 날짜와 시간을 반환한다는 것입니다. 한 날짜 열을 다른 열과 비교할 때 요일과 시간 요소를 비교하고 있습니다. 날짜의 시간 요소가 다른 경우 열이 일치하지 않습니다.

나는 이것이 당신이 원치 않는 결과를 얻는 이유라고 생각합니다. 다행히도 해결책은 아주 간단합니다. trunc()을 사용하여 날짜에서 시간 요소를 제거하십시오. 이후의 개정에 따라

SQL> select * from tab1; 

COL 
------------------- 
2017-05-09 03:25:45 
2017-05-09 06:30:32 
2017-05-09 12:20:47 

SQL> select * from tab2; 

COL 
------------------- 
2017-05-09 14:12:10 
2017-05-09 15:25:59 

SQL> select count(*) from (
    2  (select trunc(col) from tab1) 
    3   minus 
    4  (select trunc(col) from tab2)) 
    5/

    COUNT(*) 
---------- 
     0 

SQL> 

대체 솔루션 :

create table tab1 (col date)
- col의 데이터 유형이 다른 것을
가 될 수 -보다는 date 그래서 SYSDATE
- - 그것에 삽입되면, 나는 단지 10-MAY-17
을 얻는다. 시간이 아닌 날짜가 아닌 ?
는 -이 생성 문에 제어 할 수 있습니다,
- 나는에서 시간 요소를 제거합니다 tab1

create or replace trg_tab1 
before insert or update on tab1 
begin 
    :new.col := trunc(:new.col); 
end; 

이에 트리거를 구축

에 원하는대로 나는 테이블을 만들 수 있습니다 col.

insert into tab2(col) values (sysdate)
은 - 당신이

insert into tab2(col) values (trunc(sysdate)) 

는 또한 위의 같은 tab2에 트리거를 만들 삽입 할 때 나는

간단히 잘라 내기를 적용 변경에에 제어 할 수 있습니다.

이제는 두 테이블 모두에 순수한 날짜가있는 레코드가 있으므로 원래의 마이너스 쿼리는 수정하지 않고도 작동합니다.추측의 성격에


이 질문에 대한 내 가정이 공정 검사의 형태라는 것이다 : tab1 일부 초기 상태를 나타낸다는 뭔가 일이 발생하고 프로세스가 완료되면 tab2이 채워집니다 . 그렇다면 OP의 쿼리는 처리되지 않은 레코드가 없는지 확인하기위한 것입니다.

분명히 우리는 그러한 프로세스를 구현하는 더 나은 (보다 견고하고 더 정확한) 방법을 생각할 수 있지만 질문은 그러한 질문을하지 않습니다. 그리고 그렇습니다. Seekers가 리버스 엔지니어링을 수행하기보다는 구현하려는 비즈니스 로직을 설명해야한다는 것에 동의합니다.

+0

오늘 sysdate가 첫 번째 테이블에 세 번, 다른 시간에, 두 번째 테이블에 한 번만 삽입 되었다면 대답은 "zero"입니다. 요구 사항은 실제로 명확하지 않지만이 동작이 필요한 것은 아니라고 생각됩니다. – mathguy

+0

@mathguy - 당신이 만들고자하는 지점이 무엇인지 확실하지 않습니다. – APC

+1

제가하고자하는 광범위한 요점은 요구 사항을 추측하고 해결책을 제공하는 것입니다. 요구 사항이 명확하지 않을 때 일반적으로 도움이되지 않습니다. 이 특별한 경우에는'trunc (sysdate)'에 의해 요구 사항이 일치하는 것으로 생각하는 것이 매우 쉽다고 생각합니다.어떤 경우이든, OP에 관한 질문은 이것이 요구 사항인지 아닌지에 관한 내용은 내 의견에 달려 있습니다. 사실 이것이 요구 사항 일 가능성이 있습니까? – mathguy

-1

당신이 쓴 쿼리에서 0을 취득하기 위하여는, 당신은이를 사용할 수 있습니다

create table tab1 (col date); 
create table tab2 (col date); 

insert all 
    into tab1(col) values (sysdate) 
    into tab1(col) values (sysdate) 
SELECT * FROM dual; 

    commit; 

또한, minus 운영자가 당신에게 TAB1에하지 TAB2에 존재하는 행을 줄 것이다. 다른 방법으로도 결과를 알아야 할 것입니다. 나는이 경우를 사용한다 :

select count(*) (
select .. from tab1 minus select .. from tab2 
union all 
select .. from tab2 minus select .. from tab1) 

이것은 첫 번째 테이블뿐만 아니라 두 테이블의 불일치를 보여줄 것이다.

+0

첫번째 삽입물에 관해서 OP는 "나는 이것에 대한 통제권이 없다, 이것은 시스템 생성됨"이라고 말한다. 두 테이블은 어떤 형태의 검사라고 생각합니다. 그래서 INSERT ALL 솔루션은 아마도 도움이되지 않을 것입니다. 그러나 OP가 지난 주 이후로이 질문으로 돌아 가지 않았기 때문에 우리는 더 명확히 할 수 있을지는 의문입니다. – APC

+0

@ APC - 당신도 맞을지도 모르지만, 모든 경우에 삽입물이 모두 요구 사항을 충족시킬 것이라고 생각합니다.이 투표가 어디에서 왔는지 몰라도, 저것은 적어도 내가 이것을 쓰고있을 때까지 부정적인 표결이다. – g00dy