2014-11-05 2 views
0

Это продолжение моего previous question.MySQL UNION SELECT на нескольких столбцах, чтобы найти MAX MAX

Предположим, у нас есть три таблицы. Основной стол и две таблицы идентификаторов.

+-----+-----+--------------------------------------+ 
| cid | pid | date1  | date2  | date3  | 
+-----+-----+--------------------------------------+ 
| 1 | 2 | NULL  | 2014-03-24 | 2014-03-24 | 
| 3 | 1 | 2014-06-13 | NULL  | NULL  | 
| 4 | 3 | NULL  | 2014-09-14 | NULL  | 
| 2 | 1 | NULL  | NULL  | 2014-08-15 | 
| 4 | 3 | 2014-01-10 | NULL  | NULL  | 
| 1 | 4 | 2014-02-15 | NULL  | NULL  | 
| 4 | 2 | NULL  | 2014-01-06 | 2014-01-12 | 
+-----+-----+------------+------------+------------+ 

+----+----------+  +----+--------+ 
| id | city  |  | id | person | 
+----+----------+  +----+--------+ 
| 1 | 'Dallas' |  | 1 | 'John' | 
| 2 | 'Berlin' |  | 2 | 'Jack' | 
| 3 | 'Topeka' |  | 3 | 'Doug' | 
| 4 | 'London' |  | 4 | 'Pete' | 
+----+----------+  +----+--------+ 

Хорошо, теперь я хотел бы сделать выбор, чтобы получить один ряд за город в результате. Строка должна содержать город, максимум каждой даты (date1, date2, date3) этого города и человека, который принадлежит к max из трех максимальных. Результат:

+--------+--------+--------------------------------------+ 
| city | person | date1  | date2  | date3  | 
+--------+--------+--------------------------------------+ 
| Dallas | Jack | 2014-02-15 | 2014-03-24 | 2014-03-24 | 
| Berlin | John | NULL  | NULL  | 2014-08-15 | 
| Topeka | John | 2014-06-13 | NULL  | NULL  | 
| London | Doug | 2014-01-10 | 2014-09-14 | 2014-01-12 | 
+--------+--------+------------+------------+------------+ 

Mhh ... Я думал, что это не будет так сложно.

see the fiddle

+0

Почему существуют 3 даты? – Strawberry

+0

Как вы получите 2014-03-24 в date2 для Далласа в ожидаемом вами результате, когда все строки для Dallas (cid = 1) в основной таблице имеют NULL в date2? –

+0

@ Ханс: ты прав. Извините, закончите неправильную основную таблицу. Скопируйте и вставьте ошибку. Я исправлю это ... – MaggusK

ответ

1

Я думаю, что это может сработать.

select c.city, p.person, y.date1, y.date2, y.date3 
    from (select x.cid, x.date1, x.date2, x.date3, greatest(ifnull(x.date1, '0000-01-01'), ifnull(x.date2, '0000-01-01'), ifnull(x.date3, '0000-01-01')) as maxdate 
      from (select cid, max(date1) as date1, max(date2) as date2, max(date3) as date3 
        from main 
       group by cid) as x) 
       as y 
join main m 
    on m.cid = y.cid and 
    (m.date1 = y.maxdate or m.date2 = y.maxdate or m.date3 = y.maxdate) 
join city c 
    on y.cid = c.id 
join person p 
    on m.pid = p.id 

Начинает с создания «х», который представляет собой таблицу с максимальными датами для каждого города. Затем он создает «y», где он добавляет самую высокую из трех дат. Затем он соединяется с основным столом, чтобы найти строку для города с наивысшей датой. И затем он присоединяется к таблице города и человека, чтобы получить имена, а не идентификаторы.

+0

Отличный !! Я попытаюсь изучить и понять этот подзапрос ... – MaggusK

+0

Ну, это, казалось, работало первым, но когда я осмотрел, я узнал, что это не соответствует цели иметь ОДИН РЯД В ГОРОДЕ! Он находит только города, у которых есть элемент в «основной» таблице. Сравните [this] (http://sqlfiddle.com/#!2/ac731/4) с [this] (http://sqlfiddle.com/#!2/c8358/1) – MaggusK