2014-11-07 3 views
0

두 개의 테이블 중 하나에 가장 최근의 값이 저장되고 다른 하나에는 다른 모든 값이 저장되는 아카이브가 있습니다. 전달 된 날짜와 가장 가까운 위치 값을 선택하는 쿼리를 작성하고 싶습니다. 가장 최근 날짜는 항상 위치 테이블에 저장되며 이전 데이터는 항상 아카이브에 보관됩니다. 지금은 최신 테이블의 날짜 또는 날짜 보관 테이블이 더 가까운 지 여부를 확인한 후 어느 것을 선택 하는지를 확인하는 datediff가 있습니다. 내가 조인에서 아마도이 간단한 접근 방식을 찾고 있어요. select of 아래에서 볼 수 있듯이이 쿼리는 너무 좋지 않습니다. 조인 할 때 그것을 할 수있는 방법을 찾으려고 노력 중입니다. 가장 가까운 날짜는 앞으로 전달 된 날짜와 같거나 과거 인 날짜입니다. 그래서 아래의 예는 내가 다시 posid 1714에 대한 2014년 4월 6일 75800.00 다시 2240 편집에 대한 2013년 11월 5일 950.00 행을 기대할 : SQL 서버 2008R2전달 날짜에 가장 가까운 날짜로 레코드 선택

DECLARE @dtAsOFDate DATETIME= '2014-04-11' 

select a.iID 
,mp.iposid 
,CASE WHEN DATEDIFF(DAY,mp.dtASOfDate,@dtASOfdate) <= ISNULL(DATEDIFF(DAY,mpa.dtASOfDate,@dtASOfdate),999999) 
        AND DATEDIFF(DAY,mp.dtASOfDate,@dtASOfDate)>=0 
            THEN mp.dtAsOfDate 
            ELSE mpa.dtAsOFDate END 
,CASE WHEN DATEDIFF(DAY,mp.dtASOfDate,@dtASOfdate) <= ISNULL(DATEDIFF(DAY,mpa.dtASOfDate,@dtASOfdate),999999) 
        AND DATEDIFF(DAY,mp.dtASOfDate,@dtASOfDate)>=0 
            THEN mp.mPosValue 
            ELSE mpa.mPosValue END 


from #accountIDs a with (nolock) 
join positions p with (nolock)on mp.iaccountid=a.iaccountid 
left join positionsarchive mpa with (nolock) on mp.iposid=mpa.iposid 
AND mpa.dtASOfdate=(SELECT max(dtASOfDate) FROM dbo.PositionsArchive WITH (NOLOCK) WHERE  mpa.iID=iID and mpa.iPosID=iPosID and dtASOfDate<[email protected]) 

샘플 데이터 :

IID iPosID MostRecentDate MostRecentValue ArchiveDate ArchiveValue

-1427770 1714 2014년 4월 6일 75800.00 2014년 4월 2일 67800.00

-1529470 2240 2014년 11월 5일 95.00 2013년 11월 5일 950.00

+0

구문에 따라 sql-server 태그를 추가했습니다. –

+0

감사합니다. 그 부분을 놓쳤습니다. Sql Server 2008 – Jt2ouan

+0

날짜가 아카이브에 몇 개의 더 가까운 날짜를 가지고 있지 않다는 것을 어떻게 알 수 있습니까? –

답변

0

이보십시오.

DECLARE @dtAsOFDate DATETIME = '2014-04-11' 

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;  --Easier to employ than WITH (NOLOCK) 

; WITH 
    CTE1 AS 
    (
     SELECT 
      a.iaccountid 
      , mp.imanualposid 
      , mp.dtAsOfDate 
      , mp.mPosValue 
      , ABS(DATEDIFF(DAY,mp.dtASOfDate,@dtASOfdate)) AS daysAway 
     FROM #accountIDs a 
      INNER JOIN manualpositions mp ON mp.iaccountid = a.iaccountid 
     WHERE mp.iAccountID = a.iaccountid 
     UNION SELECT 
      a.iaccountid 
      , mpa.imanualposid 
      , mpa.dtAsOfDate 
      , mpa.mPosValue 
      , ABS(DATEDIFF(DAY,mpa.dtASOfDate,@dtASOfdate)) AS daysAway 
     FROM #accountIDs a 
      INNER JOIN manualpositionsarchive mpa ON mpa.iaccountid = a.iaccountid 
     WHERE mpa.iAccountID = a.iaccountid 
    ) 
    , 
    CTE2 AS 
    (
     SELECT 
      iaccountid 
      , imanualposid 
      , dtAsOfDate 
      , mPosValue 
      , RowNumber = ROW_NUMBER() OVER (PARTITION BY imanualposid ORDER BY daysAway ASC) 
     FROM CTE1 
    ) 
SELECT 
    iaccountid 
    , imanualposid 
    , dtAsOfDate 
    , mPosValue 
FROM CTE2 
WHERE RowNumber = 1 
ORDER BY 
    iaccountid ASC 
    , imanualposid ASC 
+0

나는이 선들을 따라 뭔가를 보냈지 만 CTE가 아니라 내 조인에 그것을 구축했다. – Jt2ouan

0

이것에 대해서는 outer apply라고 생각합니다. 다음 쿼리처럼 뭔가 :

DECLARE @dtAsOFDate DATETIME= '2014-04-11'; 

select a.iaccountid, mp.imanualposid, 
     (CASE WHEN ABS(DATEDIFF(DAY, mp.dtASOfDate, @dtASOfdate)) > 
        ABS(DATEDIFF(DAY, mpa.dtASOfDate, @dtASOfdate)) 
       THEN mpa.dtAsOFDate ELSE mp.dtAsOfDate 
     END) as ClosestDate 
from #accountIDs a with (nolock) join 
    manualpositions mp with (nolock) 
    on mp.iaccountid = a.iaccountid outer apply 
    (select top 1 mpa.* 
     from manualpositionsarchive mpa with (nolock) 
     where mp.imanualposid = mpa.imanualposid 
     order by abs(datediff(day, mpa.dtAsOfDate, @dtAsOfDate)) 
    ) mpa 

편집 : 당신이 이하가 가장 최근 날짜를 원하는 경우에

은, 다음 쿼리는 매우 유사하다 :

select a.iaccountid, mp.imanualposid, 
     (CASE WHEN mp.dtASOfDate > @dtASOfdate 
      THEN mp.dtAsOfDate 
      ELSE mpa.dtAsOFDate 
     END) as ClosestDate 
from #accountIDs a with (nolock) join 
    manualpositions mp with (nolock) 
    on mp.iaccountid = a.iaccountid outer apply 
    (select top 1 mpa.* 
     from manualpositionsarchive mpa with (nolock) 
     where mp.imanualposid = mpa.imanualposid and mpa.dtAsOfDate < @dtAsOfDate 
     order by mpa.dtAsOfDate desc 
    ) mpa 
+0

나는 가장 최근의 레코드를 반환하도록 case 문을 제거하고 싶다.)에서 전달 된 날짜 – Jt2ouan

관련 문제