2014-09-25 3 views
0

날짜 간격의 두 행 간의 차이를 계산하는 방법은 무엇입니까?

날짜 간격을 기준으로 Access 2010 데이터베이스의 데이터를 비교하려고합니다. 예 다양한 구매 주문서의 품목이 있으며이 품목의 창고로의 배송 내력을 유지하고자합니다. 예를 들어, 구매 주문서에는 자재 10 개 분량에 대한 요청이 있으며, 많은 납품으로 부분적으로 납품 할 수 있으며이 납품 일정이 날짜 간격에서 어떻게 달라 졌는지 알고 싶습니다. 날짜 필드를 채우기 위해 다음과 같은 기준이 사용됩니다. 항목에 QtyPending 필드의 업데이트가있는 경우, 현재 행을 booelan 필드로 비활성화하고 현재 업데이트 날짜가 QtyPending 필드를 업데이트하는 새 항목을 만듭니다. 활성 레코드는 항목의 실제 상태입니다. 그래서이 예제와 그

 
    PO   POItem   QtyPending   Date   Active 
450000/09/2014  FALSE 
450000/09/2014  TRUE 
4500000122  30    5    03/09/2014  FALSE 
4500000122  30    1    04/09/2014  TRUE 

등이 항목에 대한 정보를 보유하고 테이블이 첫 번째 항목의 경우, 날짜 01/09부터 04/09에 QtyPending 필드가 고통을하지 못했음을 의미합니다 이는 공급자가 나에게 배달을하지 않았 음을 의미하는 변형이지만, 2009 년 1 월 9 일에서 2008 년 5 월 8 일까지 그는 2 개의 수량을 나에게 배달했습니다. 두 번째 사례의 경우, 03/09부터 04/09까지 공급 업체가 4 개 수량을 제게 인도했습니다. 내가 2014년 4월 9일에 2014년 2월 9일에서 보고서 쿼리를 만드는 것 인 경우에 따라서, 예상되는 결과는 다음과 같다 :

 
    PO   POItem   QtyDelivered 
450000
4500000122  30     4 

31/08 /에서 보고서 2014 2014 년 10 월에이 보고서를 만들기 위해 내가 쿼리 함께 올라오고 있지 않다이 출력

 
    PO   POItem   QtyDelivered 
450000
4500000122  30     4 

있을 것입니다. 누구든지 나를 도울 수 있습니까?

+0

캔 날짜 스팬 두 개 이상의 기록에 걸릴 간단하지 않았다? '활성'필드는 무엇을합니까? (더 많은 질문을 따르십시오 ... 이것은 매우 명확하지 않습니다!) – Smandoli

+0

요구 사항은 이전 질문 [여기] (http://stackoverflow.com/q/26046828/2144390)과 매우 비슷하게 들립니다. 답변을 확인하고 그들 중 하나가 당신을 도울 수 있는지보십시오. ([내 대답] (http://stackoverflow.com/a/21033184/2144390)에서는 * self-join *을 사용하여 레코드 세트 루핑을 피하는 방법을 보여줍니다. –

+0

활성 필드 인 Smandoli는 FALSE 인 경우 레코드는 항목의 과거 상태를 조회하기위한 내역 목적으로 만 저장됩니다. 그리고 활성 상태가 TRUE이면 항목의 현재 상태를 의미하므로 항목의 실제 상태를 쿼리하려는 경우 수행 할 수있는 유일한 작업은 WHERE Active = TRUE입니다. –

답변

0

,

SELECT 
ItmDtIni.PO 
,ItmDtIni.POItem AS [PO Item] 
,ROUND(ItmDtIni.QtyPending - ItmDtEnd.QtyPending, 3) AS [Qty Delivered] 
,ROUND((ItmDtIni.QtyPending - ItmDtEnd.QtyPending) * ItmDtEnd.Price, 2) AS [Value delivered(US$)] 
//Filtering subqueries to bring only the items in the date interval to make a self join 
FROM (((SELECT 
     PO 
     ,POItem 
     ,QtyPending 
     ,MIN(Date) AS MinDate 
     FROM Item 
     WHERE Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy') 
     GROUP BY 
     PO 
     ,POItem 
     ,QtyPending) AS ItmDtIni 
//Self join filtering to bring only items in the date interval with the previously filtered table 
INNER JOIN (SELECT 
      PO 
      ,POItem 
      ,QtyPending 
      ,Price 
      ,MAX(Date) AS MaxDate 
      FROM Item 
      WHERE Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy') 
      GROUP BY 
      PO 
      ,POItem 
      ,QtyPending 
      ,Price) AS ItmDtEnd 
    ON ItmDtIni.PO = ItmDtEnd.PO 
    AND ItmDtIni.POItem = ItmDtEnd.POItem) 
INNER JOIN PO 
    ON ItmDtEnd.PO = PO.Numero) 
WHERE 
//Showing only items that had a variation in the date interval 
     ROUND(ItmDtIni.QtyPending - ItmDtEnd.QtyPending, 3) <> 0 
//Anchoring min date in the interval for each item found by the first subquery 
     AND ItmDtIni.MinDate = (SELECT MIN(Item.Date) 
           FROM Item 
           WHERE 
            ItmDtIni.PO = Item.PO 
           AND ItmDtIni.POItem = Item.POItem 
           AND Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy')) 
//Anchoring max date in the interval for each item found by the second subquery 
    AND ItmDtEnd.MaxDate = (SELECT MAX(Item.Date) 
          FROM Item 
          WHERE 
           ItmDtEnd.PO = Item.PO 
          AND ItmDtEnd.POItem = Item.POItem 
          AND Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy')) 
+0

다른 질문에 게시 한 것과 동일한 작업을 수행하는 훨씬 더 좋은 방법입니다. 쿼리를 작성하는이 첫 시도 후에, 나는 그것을하는 더 좋은 방법에 대해 생각했습니다. 그곳에는 다음과 같습니다 : http://stackoverflow.com/q/26465285/2726538 –

0

해결 방법에는 여러 가지가 있습니다. 가장 쉬운 방법은 단순히 두 날짜 사이에 필요한 모든 레코드를 쿼리하고 루프를 반복하여 결과를 임시 테이블에 삽입하는 것입니다. 그러면이 임시 테이블이 보고서 소스가 될 수 있습니다. 많은 사람들이 대용량 쿼리를 대신 사용하지 않고 비명을 질렀지만 가장 빠르고 간단한 방법으로 원하는 결과를 얻는 것이 가장 중요합니다.

스키마에 대한 문제는 각 레코드에 QtyDelivered가 저장되어 있지 않다는 것입니다. 당신이 그것을 가지고 있다면, 필요한 결과를 얻기 위해 그것을 합산하는 것은 쉬운 일이 될 것입니다. 이 값을 저장하지 않으면 단순하고 빠른 쿼리를 훨씬 더 어렵고 느리게 변환 할 수 있습니다.이 값을 어떤 방식 으로든 다시 계산해야하므로 두 개 이상 가질 수 있다는 사실을 잊지 않고해야합니다 기록.

이 값을 계산할 때 하위 쿼리를 사용하여 이전 행의 값을 검색하거나 왼쪽 조인 할 값을 검색 할 수 있습니다. 일단이 값을 얻으면,이 두 값을 빼서 필요한 차이를 얻을 수 있습니다. 이전 행이 없으면 Null 값의 가능성을 허용합니다. 이 값을 얻으면 그룹화 된 값으로 최종 결과를 얻을 수 있습니다. 이 계산을 수행하려면 하나 또는 두 개의 하위 쿼리 수준이 있어야합니다. 중 또 다른 하위 쿼리로이와

Select PO, POItem, QtyPending, (Select Top 1 QtyPending from MyTable T2 where T1.PO = T2.PO and T2.Date < T1.Date And (T2.Date between @Date1 and @Date2) Order by T2.Date Desc) as QtyPending2 from MyTable T1 Where T1.Date between @Date1 and @Date2) ... 

또는보기, 당신은 다음 QtyPending 및 QtyPending2의 값을 비교하여 원하는 차이를 계산할 수 있습니다 : 첫 번째 쿼리는 같은 것을해야한다 QtyPendin2가 Null 일 수 있다는 사실을 잊지 않고. 나머지 단계는 쉽게 수행 할 수 있습니다.

위 예제는 SQL Server 용이므로 Access에서는 약간 변경해야 할 수도 있습니다.어쨌든 여기서 Access에서 두 행을 비교하는 방법에 대한 많은 예제를 찾을 수 있습니다. 앞서 언급했듯이 하위 쿼리 대신 왼쪽 결합을 사용하여 행을 비교할 수도 있습니다. 나는이 문제를 해결이 쿼리를 내놓았다

+0

나는 요구 사항을 요약했다. 특정 구매 주문 배송을 추적하기 위해 SAP 보고서 인 ME2N 보고서를 작성하고 있습니다. 가져 오기에서 스프레드 시트 출력을 처리하여 더 높은 세부 수준의 항목을 추적합니다. 따라서 어떤 유형의 문제로 인해 아이템이 날짜에 전달 될 수 있고 반전 될 수 있습니다. 그것이 발생하면 QtyPending은 0에서 10로 바뀝니다. 예를 들어, 날짜 간격에 -10을줍니다. 그래서 SUM() QtyPending 나는 그 부정적인 차이를 고려하지 않았지만 주어진 아이템이 역전을 당했는지를 아는 것이 중요합니다. –

관련 문제