/ / MySQL dołącza duplikaty za pomocą instrukcji IF - mysql, join

MySQL dołącza duplikaty za pomocą instrukcji IF - mysql, join

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 |
+------+-----+------------+----------+------------+

Moje pytanie brzmi: jak zrobić to zapytanie bez duplikatu "3163"? Oto, czego się spodziewam.

+------+-----+------------+----------+------------+
| 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 |
+------+-----+------------+----------+------------+

Odpowiedzi:

2 dla odpowiedzi № 1

Możesz wyeliminować is_holiday = 0 z a MAX() agregacja, grupowanie według wszystkich innych kolumn w twoim SELECT lista.

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;