Подтвердить что ты не робот

ORDER BY date и time ПЕРЕД НАЗНАЧЕНИЕМ GROUP BY в mysql

У меня есть таблица вроде этого:

name    date         time
tom | 2011-07-04 | 01:09:52
tom | 2011-07-04 | 01:09:52
mad | 2011-07-04 | 02:10:53
mad | 2009-06-03 | 00:01:01

Сначала я хочу получить старое имя:

SELECT * 
ORDER BY date ASC, time ASC 
GROUP BY name

(- > не работает!)

теперь он должен дать мне первый сумасшедший (имеет более раннюю дату), затем tom

но с GROUP BY name ORDER BY date ASC, time ASC дает мне новый сумасшедший сначала, потому что он группирует, прежде чем он сортирует!

снова: проблема в том, что я не могу сортировать по дате и времени до группы i, потому что GROUP BY должна быть до ORDER BY!

4b9b3361

Ответ 1

Другой метод:

SELECT * 
FROM (
    SELECT * 
    ORDER BY date ASC, time ASC 
) AS sub
GROUP BY name

Группы GROUP BY по первому совпадающему результату. Если этот первый совпадение попадает именно так, как вы хотите, все должно работать как ожидалось.

Я предпочитаю этот метод, поскольку подзапрос делает логический смысл, а не накладывает его на другие условия.

Ответ 2

Я думаю, это то, что вы ищете:

SELECT name, min(date)
FROM myTable
GROUP BY name
ORDER BY min(date)

В течение времени вы должны сделать дату mysql через STR_TO_DATE:

STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s')

Итак:

SELECT name, min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))
FROM myTable
GROUP BY name
ORDER BY min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))

Ответ 4

Это сработало для меня:

SELECT *
FROM your_table
WHERE id IN (
    SELECT MAX(id)
    FROM your_table
    GROUP BY name
);

Ответ 5

Используйте подзапрос:

select name, date, time
from mytable main
where date + time = (select min(date + time) from mytable where name = main.mytable)
order by date + time;

Ответ 6

У меня была другая вариация в этом вопросе, где у меня было только одно поле DATETIME и мне понадобилось limit после group by или distinct после сортировки по убыванию в соответствии с полем DATETIME, но это что помогло мне:

select distinct (column) from
(select column from database.table
order by date_column DESC) as hist limit 10

В этом случае с полями split, если вы можете сортировать по concat, тогда вы можете уйти с чем-то вроде:

select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted

Тогда, если вы хотите ограничить, вы просто добавите свой оператор ограничения в конец:

select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted limit 10

Ответ 7

Другой способ решить эту проблему - использовать LEFT JOIN, который может быть более эффективным. Сначала я начну с примера, который рассматривает только поле даты, поскольку, вероятно, более распространено хранить дату + время в одном столбце даты и времени, и я также хочу сделать запрос простым, чтобы его было легче понять.

Итак, в этом конкретном примере, если вы хотите показать самую старую запись, основанную на столбце date, и при условии, что имя вашей таблицы называется people, вы можете использовать следующий запрос :

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date > p2.date
WHERE p2.date is NULL
GROUP BY p.name

Что делает LEFT JOIN, так это когда столбец p.date имеет минимальное значение, в левом соединении не будет p2.date с меньшим значением, и поэтому соответствующий p2.date будет NULL, Поэтому, добавляя WHERE p2.date is NULL, мы показываем только записи с самой старой датой.

И точно так же, если вы хотите показать вместо этого новейшую запись, вы можете просто изменить оператор сравнения в LEFT JOIN:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date < p2.date
WHERE p2.date is NULL
GROUP BY p.name

Теперь для этого конкретного примера, где дата + время - это отдельные столбцы, вам нужно будет каким-то образом добавить их, если вы хотите выполнить запрос на основе даты-времени двух столбцов, например:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date + INTERVAL TIME_TO_SEC(p.time) SECOND > p2.date + INTERVAL TIME_TO_SEC(p2.time) SECOND
WHERE p2.date is NULL
GROUP BY p.name

Подробнее об этом (а также о некоторых других способах достижения этой цели) можно прочитать на странице строк, содержащих максимум группы для определенного столбца.

Ответ 8

В Oracle это работает для меня

SELECT name, min(date), min(time)
    FROM table_name
GROUP BY name

Ответ 9

Это не точный ответ, но это может быть полезно для людей, которые хотят решить какую-то проблему с подходом упорядочивания строк перед группировкой в mysql.

Я пришел к этой теме, когда мне захотелось найти последнюю строку (которая order by date desc, но получить единственный результат для определенного типа столбца, который group by column name),

Еще один подход к решению этой проблемы - использовать агрегацию.

Таким образом, мы можем разрешить выполнение запроса в обычном режиме, что отсортировало asc, и введем новое поле как max(doc) as latest_doc, в котором будет указана самая последняя дата, с группировкой по одному столбцу.

Предположим, вы хотите найти данные определенного столбца сейчас, и максимальное агрегирование не может быть выполнено. В общем, для поиска данных определенного столбца вы можете использовать GROUP_CONCAT aggregator с некоторым уникальным разделителем, который не может присутствовать в этом столбце, например GROUP_CONCAT(string SEPARATOR ' ') as new_column и пока вы получаете к нему доступ, вы можете разбить/разложить поле new_column.

Опять же, это может звучать не для всех. Я сделал это, и мне тоже понравилось, потому что я написал несколько функций и не мог запустить подзапросы. Я работаю над структурой codeigniter для php.

Не уверен в сложности, может быть, кто-то может пролить свет на это.

С уважением :)