2017-05-04 10 views
1

제한된 SQL 기술로 만 마스터 할 수없는 문제에 직면하고 있습니다. 네가 나를 도울 수 있기를 바랍니다. 주어진 시간대에 특별 고객에게 유효한 품목 가격표가 있습니다.SQL에서 겹치는 가격 유효 기간 찾기

사람들은 때때로 시간차에 대해 새로운 가격을 입력하기 전에 생각하지 않기 때문에, 항목 번호와 고객 번호의 조합에 대해 겹쳐 진 시간 표시가있는 곳을 찾아야합니다. 오버랩이 진행될 때가 아니라 오버랩이 진행될 때.

Item No Customer No  Valid from Valid to  Price 
12345  55544   01.01.2016 31.05.2016 5,66 
12345  55544   01.03.2017 01.06.2017 4,55 
12345  55544   01.02.2017 01.07.2017 6,41 

당신이 올바른 방향으로 날 지점 시겠어요 :

나는 그런 데이터가있는 테이블 CustomerPrices 있나요?

감사합니다.

+1

dbms는 무엇입니까? –

+0

SSMSE를 사용하고 있습니다! – Kami

답변

0

방금 ​​다음, 중복으로 고객/항목 쌍을해야하는 경우 :

select distinct custno, itemno 
from customerprices cp 
where exists (select 1 
       from customerprices cp2 
       where cp2.custno = cp.custno and cp2.itemno = cp.itemno and 
        cp2.validfrom <= cp.validto and 
        cp2.validto >= cp.validto and 
        (cp2.validfrom <> cp.validfrom or cp2.validto <> cp.validto) 
      ); 

이 논리는 무엇입니까? 첫째, 타이밍에 완전한 중복이 없다고 가정합니다. 두 번째로, 그것은 최종 숭배를 포함하여 겹치는 부분이 있는지 확인합니다. 이것은 모든 중첩 (ABBA, ABAB)을 처리해야합니다.

+0

그건 정확히 내가 필요로했던 것입니다! 정말 고맙습니다! – Kami

0
select 
    itemno, 
    custno, 
    validfrom, 
    validto, 
    price 
from 
    CustomerPrices a 
where 
    exists (
     select 1 
     from CustomerPrices b 
     where 
      a.itemno = b.itemno 
      and a.custno = b.custno 
      and ((a.validfrom between b.validfrom and b.validto) 
       or (a.validto between b.validfrom and b.validto)) 
    ) 
0

당신은 (here 참조) 정수 표현으로 Date 형의 항목을 변환 할 수 있습니다. 이렇게하면 날짜 항목을 더 쉽게 비교할 수 있습니다.

+0

설명해 주시겠습니까? 호환되는 dbms에서의 날짜 비교는 정수 비교와 거의 같습니다. 동일한 구문과 모든 것을 사용합니다. 데이터 유형을 명시 적으로 변환하는 것이 코딩 및 실행 과정에서 낭비되는 것 같습니다. –

+0

이렇게하면 하위 쿼리와 비교하기가 더 쉬워 졌다고 생각하면 EXISTS 결과가 더 좋습니다. –

0

확실하지 않은 출력은 무엇인가요? 출력을 설명하십시오.

IT는 유효 행렬이 이전 행 validto와 겹치기 때문에 마지막 행을 반환합니다.

declare @t table(id int identity(1,1),ItemNo int,CustomerNo int 
,Validfrom date,Validto date,Price int) 
insert into @t VALUES 
(12345,55544, '2016-01-01','2016-05-31',566) 
,(12345,55544,'2017-03-01','2017-06-01',455) 
,(12345,55544,'2017-02-01','2017-07-01',641) 
select t1.* 

from @t t 
inner join @t t1 
on t.ItemNo=t1.ItemNo 
and t.CustomerNo=t1.CustomerNo 
where 
(t1.Validfrom<t.Validto) 
and t1.id-t.id=1