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'条目,我该如何进行此查询?以下是我所期待的。
+------+-----+------------+----------+------------+
| 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 |
+------+-----+------------+----------+------------+
答案 0 :(得分:2)
您可以使用is_holiday = 0
汇总消除MAX()
,并将SELECT
列表中的所有其他列分组。
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;