2015-11-12 6 views
1

Вот мой стол:Как сгруппировать по двум полям в MySQL?

gw_id |gw_payload |gw_name |gw_ref |gw_time    |gw_created_time  | 
------|-----------|--------|-------|--------------------|--------------------| 
1  |aaa  |PHP  |0.1.1 |2015-11-11 11:34:41 |2015-11-11 13:59:44 | 
2  |bbb  |PHP  |0.1.1 |2015-11-11 11:34:41 |2015-11-11 13:59:57 | 
3  |ccc  |RUBY |0.1.2 |2015-11-10 01:34:41 |2015-11-10 13:59:57 | 
4  |ddd  |RUBY |0.1.4 |2015-11-10 02:34:41 |2015-11-10 16:59:57 | 

Я хочу, чтобы захватить записи группы по gw_name и я хочу, чтобы получить последнюю gw_ref и последнюю gw_time. Так что я хочу ниже:

gw_name |gw_ref_max |gw_time_max   | 
--------|-----------|--------------------| 
RUBY |0.1.4  |2015-11-10 02:34:41 | 
PHP  |0.1.1  |2015-11-11 11:34:41 | 

Я использую этот SQL, она работает, но я не думаю, что это правильно, я волнуюсь:

select gw_name, max(gw_ref) as gw_ref_max, max(gw_time) as gw_time_max  
from tbl group by gw_name order by gw_time,gw_created_time desc 

Так что правильно SQL я должен записывать?

+0

SQL-запрос кажется мне прекрасным. Почему вы думаете, что это неправильно? – Mureinik

+0

вы хотите получить 'последний gw_ref и последний gw_time' или '' последний gw_ref и соответствующий gw_time''. Если вы хотите, чтобы оба последних, то ваш запрос выглядит нормально. Если вы хотите «последний gw_ref и соответствующее gw_time», то вы включаете условие в предложение WHERE для проверки gw_ref = (выберите max (gw_ref) из ...). – PK20

+0

@ PK20, да, я хочу, чтобы последнее соответствовало 'gw_name', @Mureinik, я беспокоюсь, потому что не думаю, что могу использовать max() в поле string (' gw_ref'). – Phoenix

ответ

1

Что делать, если max(gw_ref) не является последним в группе в соответствии с gw_created_time?

Обычно вы должны использовать ROW_NUMBER() для каждой группы для записи записей внутри каждой группы, а затем выбирать записи с помощью ROW_NUMBER = 1. В MySQL нет ROW_NUMBER() Агрегатная функция, но вы можете использовать User-Defined variables в MySQL для имитации ROW_NUMBER()

select * 
from (
    select gw_id,gw_ref,gw_time,gw_created_time, 
      @num := if(@grp = gw_name, @num + 1, 1) as row_number, 
      @grp := gw_name as dummy 
    from tbl,(select @num := 0, @grp := null) as T 
    order by gw_created_time DESC 
) as x where x.row_number = 1; 

SQLFiddle demo

Смотрите также: How to select the first/least/max row per group in SQL

+0

Где именно "tbl"? – Phoenix

+0

@Phoenix: Я изменил имя таблицы в ответе tbl. – valex

1

Если вам нужно получите последние gw_ref и gw_time соответствующие ему, вы можете использовать подзапрос.

select * from (
    select gw_name, gw_ref, gw_time 
    from tbl 
    order by gw_ref desc, gw_time desc, gw_created_time desc 
) as s 
group by s.gw_name 

Будьте осторожны с упорядочением по gw_ref, который может принимать значения, как 0.1.10 (это больше, чем 0.1.2). Вы можете попробовать заказать по номеру SUBSTRING_INDEX.

Смежные вопросы