2011-09-21 7 views
1

IBM 클라이언트 액세스 ODBC 드라이버를 통해 연결하는 DB2 데이터베이스에 대한 쿼리를 작성하고 있습니다. 'a.ofbkddt'필드를 기반으로 6 일 미만의 필드를 가져 오려면 ...이 필드는 날짜 필드가 아니라 YYYYMMDD 형식의 DECIMAL 필드입니다.DB2/ODBC의 SQL에서 날짜 계산

나는 십진 필드를 char() 호출에서 랩핑 한 다음 substr()을 사용하여 연도, 월 및 일 필드를 가져 와서 분석 할 수있었습니다. 그런 다음 이것을 날짜로 포맷하고 산술을 수행 할 수있는 숫자를 제공하는 days() 함수를 호출했습니다.

difference mydate 
2402  20050402 
2025  20060306 
... 
4   20110917 
3   20110918 
2   20110919 
1   20110920 

이 내가이 곳에서 같은 논리를 사용하지만 때 ... 볼 것으로 예상 것입니다 : 이것은 다음과 같은 산출

select 
     days(current date) - 
     days(substr(char(a.ofbkddt),1,4) concat '-'    -- YYYY- 
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM- 
      concat substr(char(a.ofbkddt),7,2)) as difference, -- DD 
     a.ofbkddt as mydate 
from QS36F.ASDF a 

: 여기

쿼리의 예 내 쿼리의 FROM 절 :

select 
     days(current date) - 
     days(substr(char(a.ofbkddt),1,4) concat '-'    -- YYYY- 
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM- 
      concat substr(char(a.ofbkddt),7,2)) as difference, -- DD 
     a.ofbkddt as mydate 
from QS36F.ASDF a 
where 
(
days(current date) - 
days(substr(char(a.ofbkddt),1,4) concat '-'   -- YYYY- 
     concat substr(char(a.ofbkddt),5,2) concat '-' -- MM 
     concat substr(char(a.ofbkddt),7,2))   -- DD 
) < 6 

나는 것이 분명하더라도, 나의 질의에서 어떤 결과를 얻을 수없는 I 오전 날짜 차이가 최소 1 일입니다 (분명히 where 절에서 요청하는 6 일보다 짧음).

내 첫 번째 생각은 반환 형식의 정수가 정수가 아니 어서 결과가 일치하지 않을 수 있다는 것이 었습니다 ... days()에 대한 설명서에 따르면 http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/rbafzmst02.htm에서 bigint를 반환합니다. 차이를 정수로 캐스팅했는데, 그냥 안전하기 위해서였습니다. 그러나 이것은 아무런 효과가 없었습니다.

답변

3

당신은 이것에 대해 거꾸로 갈 것입니다. 테이블의 모든 단일 값에 함수를 사용하지 않고 (날짜와 비교할 수 있도록), 날짜의 차이를 사전 계산해야합니다. 모든 행에서 함수를 실행하는 데 리소스가 필요합니다. CURRENT_DATE에 대해서만 수행하면 많은 비용을 절감 할 수 있습니다 (응용 프로그램 코드에서 수행 할 수 있다면 훨씬 더 절약 할 수 있습니다. 가능하지 않음). 결국 귀하의 날짜는 이며 정렬 가능한 형식으로는입니다. , 샘플 데이터 테이블에 대해 실행하면, 다음과 같은 산출

SELECT ofbkddt as myDate 
FROM QS36F.ASDF 
WHERE myDate > ((int(substr(char(current_date - 6 days, ISO), 1, 4)) * 10000) + 
       (int(substr(char(current_date - 6 days, ISO), 6, 2)) * 100) + 
       (int(substr(char(current_date - 6 days, ISO), 9, 2)))) 

:

쿼리과 같이 보이는

myDate 
============= 
20110917 
20110918 
20110919 
20110920 

당신은 또한 달력 테이블을 만들어 보길 원하는 것일 수도, 그리고 이 날짜를 열의 하나로서 추가하십시오.

+0

이것은 트릭을 만들었습니다. –

1

common table expression을 사용해보세요.

WITH A AS 
(
    select 
     days(current date) - 
     days(substr(char(a.ofbkddt),1,4) concat '-'    -- YYYY- 
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM- 
      concat substr(char(a.ofbkddt),7,2)) as difference, -- DD 
     a.ofbkddt as mydate 
    from QS36F.ASDF a 
) 
SELECT 
    * 
FROM 
    a 
WHERE 
    difference < 6 
+0

확실히이 점이 훨씬 깨끗합니다 ... 그러나 어떤 행도 반환하지 않았습니다. -/ –

+0

where 절을 제거하면 위와 같은 데이터 집합이 반환됩니다. 그렇습니까? – billinkc

+0

예, 위와 동일한 데이터 세트를 반환합니다. 나는 당황 스럽다. –

0

데이터에 a.ofbkddt의 일부 null이 있습니까? 아마도 이것은 db2가 작년보다 작게 평가하는 방식에서 다소 재미있는 행동을 일으키는 것일 수 있습니다.