2009-07-01 5 views
0

한 친구가 특정 모델에 대해 판매 된 피스가 없을 때 각 달에 각 모델의 개수가 판매 된 것을 보여주는 쿼리 작성에 대한 도움을 요청했습니다. 그날 어떤 모델의 물건도 팔리지 않은 경우에도 특정 날. 아래 쿼리를 생각해 냈지만 예상대로 작동하지 않습니다. 나는 판매 된 모델에 대해서만 기록을 남기고 있는데 왜 그런지 모르겠습니다.쿼리에 왼쪽 및 오른쪽으로 합치기

select days_of_months.`Date`, 
     m.NAME as "Model", 
     count(t.ID) as "Count" 
    from MODEL m 
    left join APPLIANCE_UNIT a on (m.ID = a.MODEL_FK and a.NUMBER_OF_UNITS > 0) 
    left join NEW_TICKET t on (a.NEW_TICKET_FK = t.ID and t.TYPE = 'SALES' 
and t.SALES_ORDER_FK is not null) 
right join (select date(concat(2009,'-',temp_months.id,'-',temp_days.id)) as "Date" 
       from temp_months 
       inner join temp_days on temp_days.id <= temp_months.last_day 
       where temp_months.id = 3 -- March 
      ) days_of_months on date(t.CREATION_DATE_TIME) = 
date(days_of_months.`Date`) 
group by days_of_months.`Date`, 
     m.ID, m.NAME 

나는 어떤 달 동안 모든 일을 얻기 위해 임시 테이블을 temp_monthstemp_days을 만들었다. MySQL 5.1을 사용하고 있지만 ANSI 호환 쿼리를 작성하려고합니다.

답변

6

당신이 상관없이 매일 모델 쌍에 대해 정확히 하나 개의 기록을 가질 수 있도록 당신은 당신의 날짜와 모델을 CROSS JOIN해야하고 LEFT JOIN 다른 테이블 :

SELECT date, name, COUNT(t.id) 
FROM (
     SELECT ... 
     ) AS days_of_months 
CROSS JOIN 
     model m 
LEFT JOIN 
     APPLIANCE_UNIT a 
ON  a.MODEL_FK = m.id 
     AND a.NUMBER_OF_UNITS > 0 
LEFT JOIN 
     NEW_TICKET t 
ON  t.id = a.NEW_TICKET_FK 
     AND t.TYPE = 'SALES' 
     AND t.SALES_ORDER_FK IS NOT NULL 
     AND t.CREATION_DATE_TIME >= days_of_months.`Date` 
     AND t.CREATION_DATE_TIME < days_of_months.`Date` + INTERVAL 1 DAY 
GROUP BY 
     date, name 

당신이 그것을 할 방법은 이제 NULL를 얻을 수 판매가없는 날에 model_id에 있으며 그룹화되어 있습니다.

참고 JOIN 조건 :

AND t.CREATION_DATE_TIME >= days_of_months.`Date` 
AND t.CREATION_DATE_TIME < days_of_months.`Date` + INTERVAL 1 DAY 

대신이, 쿼리 sargable

+0

지정 연결을 수행 할 필요가 없습니다. 나는 mysql에 익숙하지 않지만 SQL 서버에서는 inner/outer를 생략하면 inner로 기본 설정된다. –

+1

@dan s : LEFT 및 RIGHT는 OUTER을 의미합니다. – Quassnoi

+0

내 문제가 해결되었습니다. 고마워요! –

0

당신은 외부 조인을 사용해야합니다 (인덱스 최적화)하기로 도움이 될 것입니다

DATE(t.CREATION_DATE_TIME) = DATE(days_of_months.`Date`) 

의 사람들 두 조인 된 테이블의 각 레코드가 일치하는 레코드를 가질 필요는 없습니다. 당신은 OUTER을 찾고

http://dev.mysql.com/doc/refman/5.1/en/join.html

+0

쿼리를 읽으면 이미 왼쪽 및 오른쪽 외부 조인을 사용하고 있음을 알 수 있습니다. –

0

가입 할 수 있습니다. 왼쪽 외부 조인은 오른쪽에 조인 할 레코드가 없더라도 조인의 왼쪽에서 레코드가있는 결과 집합을 만듭니다. 오른쪽 외부 조인은 반대 방향에서도 동일하게 수행되며 왼쪽에 해당 레코드가 없더라도 오른쪽 테이블에 대한 레코드를 만듭니다. 레코드가없는 테이블에서 투영 된 열은 조인 결과에 NULL 값을가집니다.

관련 문제