2013-07-30 3 views
0

서브 쿼리를 기반으로 테이블 1의 날짜 열을 쿼리하고 있습니다. Subquery 1 in where 절은 외래 키 참조 테이블에서 설명을 가져오고 하위 쿼리 2는 다른 조건으로 데이터를 가져옵니다.서브 쿼리의 가능한 대안

내 질문에,이 쿼리를 더 효과적으로 만들 수있는 대안은 무엇입니까?

SELECT count(*) AS non_saturday 
FROM t_booking 
WHERE p_id IN (
     SELECT p_id 
     FROM p_detail 
     WHERE p_name IN ('A','B') 
     ) 
    AND date_format(p_date, '%Y%m%d') IN (
     SELECT DISTINCT CONCAT (
       gregorian_ccyy 
       ,gregorian_month 
       ,gregorian_day 
       ) 
     FROM m_gregorian_calendar1 c 
     WHERE c.day_of_the_week = (
       SELECT day_id 
       FROM m_gregorian_day 
       WHERE day_name = 'SATURDAY' 
       ) 
      AND c.gregorian_ccyy = '2012' 
      AND c.gregorian_month = '10' 
     ) 
+1

하나의 제안은 하위 쿼리 대신 JOIN을 사용하는 방법입니다. – Taryn

+1

@bluefeet 언급했듯이 하위 쿼리를 사용하는 대신 세 테이블에 간단하게 참여할 수 있습니다. 그러나 인덱스를 사용할 수 없으므로 테이블에 조인하기 위해 date_format/concatenation 비즈니스를 사용하고 싶지는 않습니다. –

+0

2012 년을 추가하는 것을 잊어 버렸습니다. 10 월은 양식에서 오는 것으로 하드 코딩되었습니다. 제안 된대로 내부 조인을 사용할 수는 있지만 쿼리를 읽기 쉽게 만들 것이라고 생각합니다. –

답변

2

이 어쩌면 당신의 질문에 바로 대답하지 않지만 의한 경우 (날짜와 요일 사이에 서로 다른 매핑으로 일부 일정에 반대) "토요일"당신은 바로 토요일 의미를 당신은 간단하게 실행할 수 있다는 것을 나에게 보인다

SELECT count(*) AS non_saturday 
    FROM t_booking 
    JOIN p_detail ON (t_booking.p_id = p_detail.p_id AND p_name IN ('A','B')) 
    WHERE 
     DAYOFWEEK(p_date) = 7 
     AND MONTH(p_date) = 10 
     AND YEAR (p_date) = 2012 

또는 p_date 필드를보다 효율적으로 사용 색인에

,
WHERE p_date BETWEEN "2012-10-01" AND "2012-10-31" 

(그러나 BETWEEN의 사용에 날짜 필드에 this answer도 확인하십시오.

+0

이것은 굉장합니다. dayofweek 기능에 대해 몰랐습니다. 함수의 라인을 따라 day_of_week 컬럼이있는 달력 테이블에서 필터링하는 대신 여기에서 직접 사용할 수 있습니다. 내가 이해하지 못했던 한 가지는 왜 on 절의 조건입니까? –

+0

'p_detail' 테이블은'p_name'을 기반으로 한'WHERE' 조건을 가지고 있기 때문에'JOIN'을 똑바로 만들 수 없으며'WHERE'와 같은 것을 추가해야합니다. 'JOIN' (어쩌면 인덱스도 포함)의 사용법에 대한 튜토리얼을 살펴볼 수 있습니다. – LSerni