2013-07-13 2 views
2

나는 또한 다음과 같은 데이터베이스의 휴가 응용 프로그램 테이블이MySQL은 날짜

id date   grade 
239 01/09/2012 1 
239 02/09/2012 0 
239 04/09/2012 0 
239 05/09/2012 1 
239 07/09/2012 0 
239 25/09/2012 0 
239 26/09/2012 0 

이하와 같은 MySQL 데이터베이스에 학생 출석보기를 사이에 따라 두 테이블을 조인. = 1을 승인 및 거부 된 경우 = 0

id uid from   to   status 
1 239 04/09/2012 07/09/2012 approved 
2 239 26/09/2012 26/09/2012 rejected 

지금 내가 승인 휴가와 난이 결과를 얻을 수있는 방법

id date  grade leave Fgrade 
239 01/09/2012 1     1 
239 02/09/2012 0     0 
239 04/09/2012 0  1   1 
239 05/09/2012 1  1   1  
239 07/09/2012 0  1   1 
239 25/09/2012 0     0 
239 26/09/2012 0     0 

가 알려주세요 아래 같은 학생의 최종 성적을 표시하는 쿼리를 만들려면 . 나중에 의견 제공 해명에 따라

+0

날짜 차이로 인해이 작업을 수행하는 방법을 모르겠다. –

+3

FDM 및 휴가는 어떻게 채워 집니까? –

+0

는 내가 왼쪽 atten.id =에 응용 프로그램을 가입 차렷 에서 fgrade 등이 선택 atten.id, atten.Date, atten.grade, 휴가 등 application.status, (atten.grade + application.status를) 시도 application.id application.status = 'approved'하지만 날짜를 설정하는 방법을 알지 못하고 승인 됨 = 1 –

답변

3

수정

(수정 : 성능

SELECT a.id 
    , a.date 
    , a.grade 
    , NULLIF(MAX(l.id) IS NOT NULL,0) AS leave 
    , IF(MAX(l.id) IS NULL,a.grade,1) AS fgrade 
    FROM student_attendance a 
    LEFT 
    JOIN leave_application l 
    ON l.uid = a.id 
    AND l.from <= a.date 
    AND l.to + INTERVAL 1 DAY > a.date 
    AND l.status = 'Approved' 
GROUP BY a.id, a.date, a.grade 

, 당신은 가능성 인덱스

... ON `student_attendance` (`id`, `date`, `grade`) 
... ON `leave_application` (`uid`, `status`, `from`, `to`, `uid`) 

선택 EXPLAIN 사용합니다 .. . 액세스 플랜에 대한 정보를 얻으려면.


이전

8.8.1 Optimizing Queries with Explain http://dev.mysql.com/doc/refman/5.5/en/using-explain.html는 :

나는이 지정된 결과 집합을 반환 생각합니다.

SELECT a.id 
    , a.date 
    , a.grade 
    , l.id AS leave 
    , IF(l.id IS NULL,a.grade,1) AS fgrade 
    FROM student_attendance a 
    LEFT 
    JOIN leave_application l 
    ON l.uid = a.id 
    AND l.from <= a.date 
    AND l.to >= a.date 
    AND l.status = 1 /* approved */ 

조인 술어는 학생 ID에 일치하고, 휴가 기간 내에 출석 날짜의 범위 체크뿐만 아니라 휴가 승인된다.

일치하는 (겹치는) 이탈 행이 없으면 fgrade에 등급 열의 값이 할당됩니다. 그렇지 않으면 fgrade에 1을 지정합니다.

질문에 남긴 의견에 따라 IF 함수의 세 번째 인수로 리터럴 1을 leave_application의 상태 열에 대한 참조로 바꿀 수 있습니다. 학생이 휴가를 부여 받았지만 성적을받은 경우 학년과 휴가 상태를 추가하면 원하는 것보다 더 높은 가치를 얻을 수 있습니다. 1 + 1 = 2이다.

IF(l.id IS NULL,a.grade,l.status) AS fgrade 

student_attendance의 행이 leave_application 테이블의 둘 이상의 행과 일치 할 가능성이 있습니다. 우리는 status 실제로 'Approved'를 포함하는 문자열입니다

SELECT a.id 
    , a.date 
    , a.grade 
    , MAX(l.id) AS leave 
    , IF(MAX(l.id) IS NULL,a.grade,1) AS fgrade 
    FROM student_attendance a 
    LEFT 
    JOIN leave_application l 
    ON l.uid = a.id 
    AND l.from <= a.date 
    AND l.to >= a.date 
    AND l.status = 1 /* approved */ 
GROUP BY a.id, a.date, a.grade 

경우 ... 그룹에 의해 및 집계과 그것을 해결할 수, 쿼리를 조정할 수 있습니다. leave 열의 값은 id가 아닐 수도 있습니다. leave 값은 id와 'Approved'상태에 대한 값 1과 일치하기 때문에 예제 데이터에서 알 수 없습니다. 따라서이 값은 실제로부터이 될 수 있습니다

l.status AS leave 
NULLIF(l.id IS NOT NULL,0) AS leave 
IF(l.id IS NOT NULL,1,NULL) AS leave 
(l.id/l.id) AS leave 

이러한 표현식 중 하나라도 예제 데이터에 표시된 결과를 얻을 수 있습니다.

SELECT a.id 
    , a.date 
    , a.grade 
    , NULLIF(MAX(l.id) IS NOT NULL,0) AS leave 
    , IF(MAX(l.id) IS NULL,a.grade,1) AS fgrade 
    FROM student_attendance a 
    LEFT 
    JOIN leave_application l 
    ON l.uid = a.id 
    AND l.from <= a.date 
    AND l.to >= a.date 
    AND l.status = 'Approved' 
GROUP BY a.id, a.date, a.grade 
+0

안녕하세요. 감사합니다. 출석 표에있는 날짜가 날짜/시간 형식이며 실수로 응용 프로그램에 남아있는 실수를했습니다. 날짜 형식으로 그렇게 작동하지 않습니다. 내 실수. Pls help –

+0

날짜 범위 체크'l.to + INTERVAL 1 DAY> a.date'를 수정했습니다. 이는 기본적으로 '11:59:59 PM'을 비교 대상의 'to'날짜의 시간 구성 요소로 사용합니다. 위의 경우는 자정 시간의 참석 시간입니다. 우리는> 연산자보다> 비교 연산자를 사용하므로 다음날 일치하는 자정을 피할 수 있습니다. 더러운 대안은 + INTERVAL 1 DAY + INTERVAL -1 SECOND를 사용하는 것입니다. – spencer7593

+0

새로운 것이 잘 작동하지만 너무 느립니다. –

3

시도 귀하의 질문에 대한 의견에서 제공하는 추가 정보를 기반으로 다시


, ...

SELECT a.id, a.date, a.grade, 
     CASE WHEN l.status = 'approved' THEN 1 END `leave`, 
     CASE WHEN l.status = 'approved' THEN 1 ELSE a.grade END fgrade 
    FROM attendance a LEFT JOIN `leave` l 
    ON a.id = l.uid 
    AND a.date BETWEEN l.from AND l.to 

출력 : 여기에

 
| ID |  DATE | GRADE | LEAVE | FGRADE | 
---------------------------------------------- 
| 239 | 2012-09-01 |  1 | (null) |  1 | 
| 239 | 2012-09-02 |  0 | (null) |  0 | 
| 239 | 2012-09-04 |  0 |  1 |  1 | 
| 239 | 2012-09-05 |  1 |  1 |  1 | 
| 239 | 2012-09-07 |  0 |  1 |  1 | 
| 239 | 2012-09-25 |  0 | (null) |  0 | 
| 239 | 2012-09-26 |  0 | (null) |  0 | 

입니다 데모