вот у меня есть таблица some_table в которой есть 3 поля: id, item_id, date 1 1 1000 2 1 5001 3 2 1245 4 2 8723 5 3 3462 6 1 2222 Нужно получить список элементов отсортированных по дате, но что бы элементы не повторялись отображает список уникальных элементов отсортированных по дате в котором для каждого элемента дата самая последняя (наибольшая) 4 2 8723 5 3 3462 2 1 5001 Я очень извиняюсь возможно плохо изложил вопрос, но я уже мозг поломал.
перечитал и самому теперь плохо понятно. Вот ещё, как вариант: есть та же самая таблица id, item_id, date 1 1 1000 2 1 5001 3 2 1245 4 2 8723 5 3 3462 6 1 2222 сортируем её по дате в обратном порядке 4 2 8723 2 1 5001 5 3 3462 6 1 2222 3 2 1245 1 1 1000 и теперь выбираем каждое первое уникальное вхождение item_id 4 2 8723 2 1 5001 5 3 3462 вот это мне надо получить пожалуйста подскажите, очень надо
уже пробовал, но это не то что мне надо данный запрос сначала выбирает уникальные а потом сортирует их по дате, и в результатах у меня не то что надо то же самое если делать [sql]SELECT * FROM table GROUP BY item_id ORDER BY date DESC[/sql]
[sql]SELECT MAX(id) FROM table GROUP_BY item_id[/sql] Остальную информацию извлекать по списку этих ID Есть еще такой вариант [sql]SELECT * FROM table GROUP BY item_id HAVING id = MAX(id)[/sql]
Тоже выдаёт не то =(((( кстати, нашёл "уродский" способ получить то что мне надо, только вот он ОЧЕНЬ тяжёлый и это 100% не выход сначала сортирую всю таблицу по дате [sql]ALTER TABLE `table` ORDER BY `date` DESC[/sql] а потом выбираю уникальные значения [sql] SELECT DISTINCT `item_id` FROM `table`[/sql] результат, который нужен, но это совершенно не подходит. и по понятным причинам я не могу сделать key-ем поле с датой, а когда добавляю новые строки в таблицу, то они просто вписываются в конец нарушая порядок может быть есть такой запрос, который будет вписывать строку в уже отсортированную таблицу, не нарушая порядка??
Это невозможно. Строго говоря при DISTINCT и GROUP BY MySQL для неодинаковых значений столбцов в группе может выдать любое из них. Сделайте как я писал, сначала выберите SELECT MAX(id) FROM table GROUP_BY item_id затем выберите нужную информацию по этим записям. Если MAX(id) не соответствует MAX(date) а нужна сортировка именно по дате, то выбрать соответственно ее и сделать джойн на эту же таблицу опять для получения id
[sql]SELECT MAX(date_c) FROM some GROUP_BY item_id[/sql] это выдавало не то что надо, и "не таким" был именно idшник теперь сделал с JOINом, но проблема осталась такой же =(( [sql]SELECT MAX( s.date_c ) AS 'date', s2.id, s.item_id, s2.date_c FROM some AS s JOIN some AS s2 WHERE s2.date_c = s.date_c GROUP BY s.item_id ORDER BY s.date_c DESC LIMIT 0 , 30[/sql] или [sql]SELECT MAX( s.date_c ) AS 'date', s2.id, s.item_id, s2.date_c FROM some AS s JOIN some AS s2 ON s2.date_c = s.date_c GROUP BY s.item_id ORDER BY s.date_c DESC LIMIT 0 , 30[/sql] s.date_c и item_id правильные, а вот idшники выдаёт те, которые соответсвуют первым вхождениям в таблице ну и конечно же s2.date кривые =\ может быть я неправильно JOIN использую?
Значит обращаю внимание на следующие вещи. 1. дата не идентифицирует однозначно запись. 2. у записи есть 3 поля - id (уникальный вообще в таблице), item_id, date_c Что нужно? Нужно выбрать запись id, item_id, date_c Если мы будем выбирать только по date_c, то мы получим кучу разных записей с разным item_id Это несколько не то, что надо. Поэтому при условии что для каждого item_id date_c не повторяется, мы можем однозначно определить запись по этим двум полям. Соответственно при выборке с группировкой, нам нужно выбирать не только MAX(date_c), но и сам item_id к которому принадлежит этот date_c И дальше JOIN делать по условию на 2 этих поля, а не на одно date_c Ну и форма записи JOIN такова [sql]SELECT поля FROM таблица JOIN таблица ON условия(т.е. неравенств тут может быть несколько соединенных логическими операторами) [/sql]
Ругается, если я пишу: [sql]ON s.item_id = s2.item_id AND s2.date_c = MAX(s1.date_c)[/sql] и насколько я понимаю нельзя использовать MAX(s1.date_c) в ON а если просто пишу [sql]ON s.item_id = s2.item_id AND s2.date_c = s1.date_c[/sql] выдаёт неправильные результаты и скорее всего потому что тут проблема [sql]SELECT MAX( date_c ) , date_c FROM some GROUP BY item_id LIMIT 0 , 30[/sql] результаты, которые возвращает запрос противоречат здравому смыслу, потому что в первой и второй колонке данные различаются и в первой, действительно то что мне надо, а во второй первые вхождения item_id и есть другая проблема, не нужно получить не пары item_id - date_c а именно id-шники
ставим алиас, как уже делали выше и в используем именно алиас, а не MAX() id надо брать из 2й таблицы, той которая будет джойниться.
если я вас понял, то в упрощённом варианте должно быть, что то подобное: [sql] SELECT MAX( date_c ) AS 'hehe', date_c FROM some WHERE date_c = hehe GROUP BY item_id LIMIT 0 , 30 [/sql] и соответственно ошибка:[sql]Unknown column 'hehe' in 'where clause' [/sql] я только недавно полез в SQL, так что многого не знаю, если вам не сложно, то пишите чуточку подробнее(как для чайнков) =)
В упрощенном виде это работать не будет. В некоторых случаях невозможно использовать алиасы непосредственно в условиях запроса. Тогда нужно сделать подзапросом примерно так [sql]SELECT t.alias FROM (SELECT field as alias FROM table) as t[/sql] и дальше JOIN с исходной table Чуточку подробнее это готовый код. Поэтому давайте разбираться в таком варианте. Как только вы поймете механику - все будет очень просто.
Я вижу 2 варианта: 1) а) Приведенный ранее но чуть измененный "SELECT MAX( date_c )... GROUP BY item_id." И джойнить к нему выборку id. б) Вывернуть на лицевую сторону предыдущий запрос. 2) Запрос со связанным подзапросом.
[sql]SELECT t.max_date, s.item_id, s.id FROM ( SELECT MAX( date_c ) AS max_date FROM some ) AS t JOIN some AS s ON t.max_date = s.date_c GROUP BY s.item_id ORDER BY s.date_c DESC LIMIT 0 , 30[/sql] выдаёт нужную строку, НО (!) только одну =( где я опять напортачил? а можно по-подробней?
Группировка должна быть в подзапросе, а не в JOIN, ведь мы же хотим выбрать список item_id с нужной нам датой. В запросе с JOIN уже будут исключительно нужные значения.