Выбор рядов с уник. полем

GrayMaster

Новичок
Выбор рядов с уник. полем

Добрый день !
Возник следующий вопрос:
как выбарть ряды, у которых одно поле - уникальное ?
Знаю способы:
DISTINCT - не подходит, т.к. нужно выбраться все столбцы а не один
GROUP BY - не подходит т.к. уходит много времени на сортировку, а сортировать - не нужно...

Спасибо.
 

440hz

php.ru
GROUP BY не сортирует он группирует а порядок записей определяется внутренним порядком хранения данных.
 

kewluser

Новичок
Чесно говоря ничего не понял. Опиши подробнее структуру таблицы, и какую выборку ты из неё хочешь получить.

P.S. А под рядами имеются в виду записи в таблице?
 

zerkms

TDD infected
Команда форума
440hz
ошибаешься, GROUP BY сортирует по группируемому полю

"If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns."

GrayMaster
честно говоря - не могу представить случая - когда нужно/можно не сортировать выборку - получишь ведь непредсказуемый результат

попробуй наверное добавь на это поле индекс
 

kewluser

Новичок
2 zerkms

"GROUP BY" может присутствовать только в таких запросах, в которых есть агрегатные функции (f.e.: max,min,avg,count) и в общем случае для упорядочевания данных полученных select'ом применятся не может.
 

zerkms

TDD infected
Команда форума
kewluser
ты на 100% уверен в своих словах или это твоё имхо?
 

kewluser

Новичок
Group BY оператор группировки данных, после применения агрегатных функций в запросе.

Возможно, как вырожденный случай, если в запросе отстутствуют агрегатные функции, но присутстствует GROUP BY СУБД будет действительно возвращать упорядоченные данные, по полям перечисленным в Group BY. В этом случае Group BY вырождается до Order BY.

Еще раз. Group BY должен применятся не как оператор упорядочевания результата запроса, а как оператор группировки в случае применения агрегатных функций
 

zerkms

TDD infected
Команда форума
kewluser
;)
Group BY должен применятся не как оператор упорядочевания результата запроса, а как оператор группировки в случае применения агрегатных функций
повторяю ещё раз:
если нужно получить набор записей, из которых одно поле уникальное, и НЕ НУЖНО НИКАКИХ АГРЕГАТНЫХ ФУНКЦИЙ (как в текущем случае - перечитай вопрос) - то используется GROUP BY

Возможно, как вырожденный случай, если в запросе отстутствуют агрегатные функции
агрегатные функции никак не влияют на группировку, они лишь делают возложенную на них работу
 

ForJest

- свежая кровь
Странная постановка задачи
есть вот допустим
1 | 1
1 | 2
2 | 3
2 | 4

По первой колонке нужно найти уникальные. Что должно быть во второй колонке?
1, 3? 2, 4? 1, 4? 2, 3?
 

zerkms

TDD infected
Команда форума
ForJest
хехе ;)
а это уже как бы зависит от ситуации...

просто представим что вопрошающий понимает что ему нужно и зачем
 

kewluser

Новичок
2 zerkms
я тебе не про исходный вопрос толкую, а про то когда надо использовать Order By, когда Group By

ну ты вроде это и сам понимаешь

-~{}~ 28.02.06 12:27:

2 zekrms

Кажется понял в чем я заблуждался. Если у нас в запросе есть оператор группировки для какого-либо, и при этом агрегатные функции отстутствуют, то будут выбраны только уникальные значения, причем упорядоченно.

т.е.

select id from table group by id
эквивалентно
select distinct id from table [order by id]
 

Wicked

Новичок
kewluser, что-то ты не то говоришь :)
1) "GROUP BY" может присутствовать только в таких запросах, в которых есть агрегатные функции (f.e.: max,min,avg,count) и в общем случае для упорядочевания данных полученных select'ом применятся не может.

Неверно. Group by дает возможность использовать агрегатные функции. Единственное исключение: когда в качестве столбцов выбираются только агр. функции - тогда все записи оригинальной выборки расцениваются как одна группа.

2) Group BY оператор группировки данных, после применения агрегатных функций в запросе.

Неверно. Group by обуславливает группы, для каждой из которых считаются агр. функции. Затем от каждой из групп возвращается по одной записи, содержащей значения агр. функций и/или некоторый набор полей [вычисленных от] одного представителя группы.

3) Возможно, как вырожденный случай, если в запросе отстутствуют агрегатные функции, но присутстствует GROUP BY СУБД будет действительно возвращать упорядоченные данные, по полям перечисленным в Group BY. В этом случае Group BY вырождается до Order BY.

Неверно. Group by все так же создаст группы. И из каждой группы возьмет по произвольному представителю. Если есть записи
1, 2
1, 3
и мы делаем group by field1, то mysql, руководствуясь своими личными непредсказуемыми пристрастиями, вернет либо
1, 2
либо
1, 3
 

kewluser

Новичок
Насчет Group By согласен, я понимал этот опреатор узко, в контексте агрегатных функций
 

newARTix

Новичок
Извиняюсь, если тема устарела...

Сергей Тарасов,
Данный запрос не работает, т.к. DISTINCT применяется ко всему SELECT, а не к отдельным полям.

У меня в данный момент похожая с топик-стартером проблема.

Есть таблица с историей изменения каких-то величин:

id | key | value | time

id - auto_increment, первичный ключ
key - название переменной
value - значение переменной
time - время в которое это значение было зафиксировано.

Нужно одним запросом выбрать последние значения каждой переменной.
То есть, по примеру ForJest, чтобы вернулось две записи:
1|2
2|4

ORDER BY `time` DESC не подходит потому что в одну выборку попадает несколько записей об одной и той же переменной, которая часто редактируется, а те что редко редактируются оказываются в самом конце выборки. Если вообще не обрезаются LIMIT'ом.
ORDER BY `key` ASC, ORDER BY `time` DESC тоже бессмысленен.
ORDER BY `time`DESC, ORDER BY `key` ASC аналогично.

Как я уже сказал DISTINCT выбирает только полностью уникальные записи, для всего SELECT.
GROUP BY дает непредсказуемые результаты по сортировке, то есть результаты сортируются только после объединения, а как уж они там объединятся... только MySQL ведает.
Как извратиться с помощью COUNT и HAVING пока не придумал, да и сдается мне что производительность такого запроса с ростом количества записей будет резко падать...


Буду благодарен за подсказку.
 

korchasa

LIMB infected
Первое, что приходит в голову - еще одна таблица + INSERT ... ON DUPLICATE KEY UPDATE
 

Gas

может по одной?
korchasa
ну это как-то брутально.

чё-то типа такого должно сработать:
[sql]
select t2.* from (select `key`,max(`time`) as `time` from tbl group by `key`) as t
join tbl as t2 on t.`key`=t2.`key` and t.`time`=t2.`time`;
[/sql]
толькл очень желательно составной индекс (`key`, `time`)
 

korchasa

LIMB infected
Автор оригинала: Gas
korchasa
ну это как-то брутально.
Просто это первое, что пришло в голову, т.к. на днях решал такую же проблему на большом логе, где self join + group by не прокатывает.

ЗЫ: А зачем их склеивать по time и key, если primary id есть?
 
Сверху