2012-07-26 3 views
1
mysql> describe holidays; 
+---------+-------------+ 
| Field | Type  | 
+---------+-------------+ 
| hid  | int(11)  | 
| name | varchar(32) | 
| date | date  | 
| enabled | int(1)  | 
+---------+-------------+ 

mysql> 

mysql> describe locations; 
+----------+--------------+ 
| Field | Type   | 
+----------+--------------+ 
| lid  | int(11)  | 
| code  | char(2)  | 
| location | varchar(255) | 
| enabled | int(1)  | 
+----------+--------------+ 

mysql> describe holidays_locations; 
+-------+---------+ 
| Field | Type | 
+-------+---------+ 
| hid | int(11) | 
| lid | int(11) | 
+-------+---------+ 

mysql> SELECT DISTINCT timesheet.tid, timesheet.uid, timesheet.date, timesheet.location, 
IF (timesheet.date = holidays.date AND timesheet.location = holidays.lid, 1, 0) AS is_holiday 
FROM (`timesheet`) 
LEFT JOIN (SELECT holidays.name AS holiday, locations.location as location, holidays.date AS date, locations.lid AS lid 
      FROM holidays_locations 
      INNER JOIN holidays ON holidays_locations.hid = holidays.hid 
      INNER JOIN locations ON holidays_locations.lid = locations.lid) AS holidays ON holidays.date = timesheet.date 
WHERE `uid` = '12' 
AND `timesheet`.`date` >= '2012-05-16' 
AND `timesheet`.`date` <= '2012-05-31' 
ORDER BY date; 

+------+-----+------------+----------+------------+ 
| tid | uid | date  | location | is_holiday | 
+------+-----+------------+----------+------------+ 
| 2962 | 12 | 2012-05-18 | 5  |   0 | 
| 3163 | 12 | 2012-05-21 | 9  |   1 | 
| 3163 | 12 | 2012-05-21 | 9  |   0 | 
| 3162 | 12 | 2012-05-21 | 5  |   0 | 
+------+-----+------------+----------+------------+ 

제 질문은 중복 된 '3163'항목없이 어떻게 수행합니까? 다음은 내가 기대하는 바입니다.MySQL이 IF 문과 함께 중복됩니다.

+------+-----+------------+----------+------------+ 
| tid | uid | date  | location | is_holiday | 
+------+-----+------------+----------+------------+ 
| 2962 | 12 | 2012-05-18 | 5  |   0 | 
| 3163 | 12 | 2012-05-21 | 9  |   1 | 
| 3162 | 12 | 2012-05-21 | 5  |   0 | 
+------+-----+------------+----------+------------+ 

답변

2

당신은 당신의 SELECT 목록에있는 모든 다른 열을 기준으로 그룹화하는 MAX() 집계로 is_holiday = 0을 제거 할 수 있습니다.

SELECT 
    DISTINCT timesheet.tid, 
    timesheet.uid, 
    timesheet.date, 
    timesheet.location, 
    /* MAX aggregate will take only the 1, not 0 */ 
    MAX(IF (timesheet.date = holidays.date AND timesheet.location = holidays.lid, 1, 0)) AS is_holiday 
FROM (`timesheet`) 
LEFT JOIN (SELECT holidays.name AS holiday, locations.location as location, holidays.date AS date, locations.lid AS lid 
      FROM holidays_locations 
      INNER JOIN holidays ON holidays_locations.hid = holidays.hid 
      INNER JOIN locations ON holidays_locations.lid = locations.lid) AS holidays ON holidays.date = timesheet.date 
WHERE `uid` = '12' 
AND `timesheet`.`date` >= '2012-05-16' 
AND `timesheet`.`date` <= '2012-05-31' 
/* And GROUP BY all other selected columns */ 
GROUP BY 
    timesheet.tid, 
    timesheet.uid, 
    timesheet.date, 
    timesheet.location 
ORDER BY date;