2012-01-24 4 views
1

MS 액세스 코드의이 부분에서 고객 가입시 MAX 날짜를 얻으려고합니다. 먼저 집계 함수로 작업 할 수 있도록 날짜를 변환해야합니다. 불행히도 날짜 열에 null 인 영역이 있습니다.해결 방법 또는 해결 방법 오류 : 잘못된 Null 사용?

오류가 발생했습니다 일부 누락 된 날짜로 인해 null이 잘못되었습니다.

어떻게 해결할 수 있습니까? 해결 방법이 있습니까?

SELECT CUSTOMER.FIRST_NAME, 
    MAX(DateSerial(CInt(Left([CUSTOMER.SIGNUP_DATE],4)),CInt(Mid([CUSTOMER.SIGNUP_DATE],5,2)),CInt(Right([CUSTOMER.SIGNUP_DATE],2)))) AS SIGN_DATE, 
    (DateSerial(CInt(Left([CUSTOMER.LEAVE_DATE],4)),CInt(Mid([CUSTOMER.LEAVE_DATE],5,2)),CInt(Right([CUSTOMER.LEAVE_DATE],2)))) AS LEV_DATE 
FROM CUSTOMER 
WHERE ((DateSerial(CInt(Left([CUSTOMER.SIGNUP_DATE],4)),CInt(Mid([CUSTOMER.SIGNUP_DATE],5,2)),CInt(Right([CUSTOMER.SIGNUP_DATE],2)))) <=Date()) 
    AND ((DateSerial(CInt(Left([CUSTOMER.LEAVE_DATE],4)),CInt(Mid([CUSTOMER.LEAVE_DATE],5,2)),CInt(Right([CUSTOMER.LEAVE_DATE],2)))) =#012/31/2012#) 
GROUP BY 
    CUSTOMER.FIRST_NAME, 
    CUSTOMER.SIGNUP_DATE, 
    CUSTOMER.LEAVE_DATE; 
+2

제안 :보기를 만들라는 말을 'CurrentCustomers' 그 NULL 'LEAVE_DATE'로 고객을 걸러 내고 VIEW를 타켓팅합니다. 그러나 당신은 정말로이 텍스트를 날짜 열을 실제 시간 가치로 영구히 대체해야합니다. 즉석에서이를 수행하려고 시도하십시오. – onedaywhen

+0

감사! 먼저 집계를 추가하는 것보다 null을 필터링하는 것에 대해 생각하고있었습니다. 테이블은 Access에 연결되어 있으므로 해당 텍스트 값을 날짜로 변환해야합니다. – Asynchronous

+1

괄호 안에 이름을 넣으면 제대로 작동합니까? 예를 들어서는 안됩니다. '[CUSTOMER.SIGNUP_DATE]'대신 [[CUSTOMER]. [SIGNUP_DATE]'입니까? 나는 MS Access 직원이 아니므로 바보 같은 질문이라면 실례합니다. –

답변

1

귀하의 SIGNUP_DATE 필드가이 형식의 문자열로 날짜를 포함합니다 : "20120131"여기

는 코드입니다. 따라서 Left(), Mid() 및 Right() 함수를 사용하여 연도, 월 및 일 하위 문자열을 분리하고 CInt()로 숫자로 변환 한 다음 마지막으로 DateSerial()에 해당 숫자를 입력합니다.

날짜 문자열 만 3 부분 사이에 적절한 구분 기호가 포함 된 경우 문자열을 CDate()에 공급할 수 있습니다 (예 : CDate ("2012-01-31")). 그래서 당신이 쿼리에서 문자열에 구분 기호를 추가하고 CDate()에 피드를 제안합니다.

여기 내 단순화 고객 테이블이다

id SIGNUP_DATE 
1 20120130 
2 
3 20120131 

이 쿼리 날짜/시간 값을 비 - 널 SIGNUP_DATE 값을 변환하여 SIGNUP_DATE가 NULL 행 파기 (ID = 2 행은 제외된다).

SELECT 
    id, 
    CDate(Left(SIGNUP_DATE,4) & "-" 
     & Mid(SIGNUP_DATE,5,2) & "-" & 
     Right(SIGNUP_DATE,2)) 
     AS SIGN_DATE 
FROM CUSTOMER 
WHERE SIGNUP_DATE Is Not Null; 

그러면 최대 값을 얻는 것은 간단합니다.

SELECT Max(q.SIGN_DATE) AS MaxOfSIGN_DATE 
FROM (
     SELECT 
      id, 
      CDate(Left(SIGNUP_DATE,4) & "-" 
       & Mid(SIGNUP_DATE,5,2) & "-" & 
       Right(SIGNUP_DATE,2)) 
       AS SIGN_DATE 
     FROM CUSTOMER 
     WHERE SIGNUP_DATE Is Not Null 
    ) AS q; 

편집 : 어떤 샘플 데이터에 대해 테스트 없음으로, 나는거야 단지 날개를하고이 쿼리를 시도 제안 :

SELECT 
    q.FIRST_NAME, 
    #2012/12/31# AS LEV_DATE, 
    Max(q.SIGN_DATE) AS MaxOfSIGN_DATE 
FROM (
     SELECT 
      FIRST_NAME, 
      CDate(Left(SIGNUP_DATE,4) & "-" 
       & Mid(SIGNUP_DATE,5,2) & "-" & 
       Right(SIGNUP_DATE,2)) 
       AS SIGN_DATE 
     FROM CUSTOMER 
     WHERE 
      SIGNUP_DATE Is Not Null 
      AND LEAVE_DATE = "20121231" 
    ) AS q 
GROUP BY 
    1, 
    2; 
+0

매우 귀중한 의견을 보내 주셔서 감사합니다! MAX 함수의 경우 가장 높은 날짜의 고객을 선택하려고하지 않습니다. 고객이 더 많은 경우 가장 높은 가입 날짜를 선택하려고합니다. 고객이 두 개의 날짜가있는 경우를 말합니다. 2011 년 1 월 1 일과 2012 년 1 월 2 일에 가장 높은 값을 원한다면 코드가 전체 열에서 가장 높은 날짜를 표시합니다. – Asynchronous

+0

예, 그렇게하기가 쉽습니다. 동일한 원칙을 사용하고 원래 GROUP BY 쿼리에 적용합니다. 쿼리에서 반환 된 전체 레코드 집합에 대해 한 번만 수행하는 것이 아니라 각 그룹에 대해 Max()를 계산합니다. – HansUp

+0

예, 기록은 해당 날짜 값이있는 경우에만 수집됩니다. 원래 MAX의 전체 아이디어는 가장 높은 날짜를 얻는 것이 었습니다. 그 때 널 오류가 발생했습니다. 그러나 기록은 건너 뛸 수 있습니다. 매우 간단한 쿼리입니다. 그것이 null이면 건너 뛰고 가장 높은 날짜를 얻습니다. 예 LEAVE_DATE는 그 길을 계속 유지할 수 있습니다. 배우기 위해 이상한 점을 만들어 냈습니다. – Asynchronous