[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: MySQL -> DISTINCT не срабатывает...
inpost
Доброе утро всем, прошу помощи. Не получается использовать DISTINCT, если указываю SELECT DISTINCT `cat` - то работает, если мне надо взять не только одно поле, но и второе: SELECT DISTNCT `cat`,`name` - уже не хочет работать DISTINCT вообще. Буду рад помощи, вот сам скрипт обращения к БД:

    $res2 = mysqlQuery("SELECT DISTINCT `cat`,`girl`
FROM `dat_daterussianbride`
WHERE `cat` IN (1,2,3,4,5,6,7,8)
ORDER BY RAND()
LIMIT 8
"
);

Когда указываю 2, то результат запроса таков:
10190 - 1
10171
- 8
10192
- 2
10160
- 7
10155
- 5
10172
- 2
10148
- 1
10158
- 6
Как видите, цифра 1 повторилась дважды...
Дамп:
--
-- Структура таблицы `dat_daterussianbride`
--

CREATE TABLE IF NOT EXISTS `dat_daterussianbride` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`girl` int(11) NOT NULL,
`cat` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

--
-- Дамп данных таблицы `dat_daterussianbride`
--

INSERT INTO `dat_daterussianbride` (`id`, `girl`, `cat`) VALUES
(1, 10148, 1),
(2, 10172, 2),
(3, 10152, 3),
(4, 10153, 4),
(5, 10155, 5),
(6, 10158, 6),
(7, 10160, 7),
(8, 10171, 8),
(9, 10190, 1),
(10, 10192, 2);


Вообще скрин предоставлю: http://my.jetscreenshot.com/demo/20110402-64pm-37kb



Спустя 45 минут, 53 секунды (2.04.2011 - 08:00) alex12060 написал(а):
SELECT DISTINCTROW `cat` , `girl`
FROM `dat_daterussianbride`
WHERE `cat`
IN ( 1, 2, 3, 4, 5, 6, 7, 8 )
ORDER BY RAND( )
LIMIT 8

Спустя 4 минуты, 22 секунды (2.04.2011 - 08:04) inpost написал(а):
alex12060
http://my.jetscreenshot.com/demo/20110402-dzrp-37kb - результат тот же! 1 и 1 повторилось дважды.

Спустя 1 минута, 23 секунды (2.04.2011 - 08:05) alex12060 написал(а):
О, вижу.
хмм...

Спустя 30 минут, 27 секунд (2.04.2011 - 08:36) alex12060 написал(а):

SELECT DISTINCTROW `cat` , `girl`
FROM `dat_daterussianbride`
WHERE `cat`
IN ( 1, 2, 3, 4, 5, 6, 7, 8 )
GROUP BY `cat`
ORDER BY RAND( )
LIMIT 8


Надеюсь сработает)

Спустя 5 минут, 5 секунд (2.04.2011 - 08:41) inpost написал(а):
alex12060
Ты бы хоть сам попробовал, прежде чем советовать. Группировка всегда идёт раньше сортировки, ключевым в данном случае является именно сортировка RAND()

Спустя 18 минут, 9 секунд (2.04.2011 - 08:59) alex12060 написал(а):
Я пробовал. Лично у меня работает все нормально.

Спустя 7 минут, 37 секунд (2.04.2011 - 09:07) inpost написал(а):
alex12060
У тебя будет всегда запись эта: (1, 10148, 1), а этой (9, 10190, 1), НИКОГДА не будет из-за того, что сгруппировалось ещё до сортировки, а мне в данном случае нужна случайная девушка.

Спустя 18 минут, 23 секунды (2.04.2011 - 09:25) alex12060 написал(а):
Ну хмм...
Ладно, я не в силах помочь тогда.
Попробуй с UNION
Ну, или, либо попробуй делать тогда с помощью php либо удалять ненужные значения, либо shuffle()

Спустя 1 час, 14 минут, 58 секунд (2.04.2011 - 10:40) sergeiss написал(а):
inpost - у тебя проблема в том, что ты пытаешься получить результат одним простым запросом. А ты немного шире посмотри :)

Попробуй так сделать. Давай твой запрос обозначим для краткости как YOUR_SQL. Только укажи там количество в лимите не 8, а 20. Чтоб с запасом.

И сделай такой запрос (на месте YOUR_SQL впиши твой запрос):
SELECT DISTINCT  `cat`, `girl`
FROM (YOUR_SQL) `your_sql`
LIMIT 8


Что произойдет? Сначала будет сделана твоя нынешняя выборка, из которой ты затем выберешь действительно уникальные строки.

Спустя 9 минут, 27 секунд (2.04.2011 - 10:49) Snus написал(а):
inpost
Для группировки по нескольким полям существует GROUP BY
SELECT `cat`,`girl`
FROM `dat_daterussianbride`
WHERE `cat` IN (1,2,3,4,5,6,7,8)
GROUP BY `girl`
ORDER BY RAND()
LIMIT 8


SELECT DISTINCT (`girl`), `cat`
FROM `dat_daterussianbride`
WHERE `cat` IN (1,2,3,4,5,6,7,8)
ORDER BY RAND()
LIMIT 8

Спустя 3 минуты, 49 секунд (2.04.2011 - 10:53) Trianon написал(а):
DISTINCT - требование в отклике запроса убрать все дубли повторяющихся строк результата, а не отдельных полей.
Так что DISTINCT работает совершенно нормально.

Как составить запрос не подскажу, потому что не понял, какие данные хочется от него получить.
И желательно без RAND().
RAND() и LIMIT это вообще надстройки чисто MySQL-ные, а не операции реляционной алгебры.

Спустя 28 минут, 38 секунд (2.04.2011 - 11:22) sergeiss написал(а):
М-да... Подумал и понял, что мой предыдущий ответ не совсем правильный... В Постгре я бы тебе сразу сказал, как правильно будет сделать smile.gif

Спустя 56 минут, 54 секунды (2.04.2011 - 12:19) alex12060 написал(а):
Snus

У тебя и в 1 и во 2 запросе есть повторяющиеся элементы.

Спустя 36 минут, 3 секунды (2.04.2011 - 12:55) Snus написал(а):
alex12060
Это потому, что группировка по полю girl (их повторений не может быть по определению)

Если нужно по cat группировать, то

SELECT `cat`,`girl`
FROM `dat_daterussianbride`
WHERE `cat` IN (1,2,3,4,5,6,7,8)
GROUP BY `cat`
ORDER BY RAND()
LIMIT 8




SELECT DISTINCT (`cat`), `girl`
FROM `dat_daterussianbride`
WHERE `cat` IN (1,2,3,4,5,6,7,8)
ORDER BY RAND()
LIMIT 8

Спустя 2 часа, 28 минут, 48 секунд (2.04.2011 - 15:24) alex12060 написал(а):
Первый твой пост, он похож на мой последний, но его inpost разнес в пух и прах.
А 2 тоже выводит повторяющиеся значения.

Или я чего-то не понимаю?..

Спустя 1 час, 52 секунды (2.04.2011 - 16:24) inpost написал(а):
Trianon
8 категорий всего, из них надо взять для каждой категории по 1 девушке случайной, которая относится к этой категории. Хочется получить 8 записей с уникальным `cat`. А можно ли уникальность по отдельному полю хоть как-то сделать?

Snus
Если делать GROUP до ORDER BY, то перемешки не будет девушек, а надо именно случайную девушку, то есть ORDER BY RAND() должен пройти первым.
Во второй вариант попадают девушки из первой категории дважды.

RAND должен быть именно для этих записей и взяться лишь одна из них: (1, 10148, 1) и (9, 10190, 1); а так же: (2, 10172, 2) и (10, 10192, 2); то есть именно уникальная категория.

Просто покажу для точной наглядности какой запрос я пытался оптимизировать (я исходил из того, что сначала написал простой, чтобы работал, а потом его хотел оптимизировать из 17 запросов в 3):
$res = mysqlQuery("SELECT `id`,`name` 
FROM `"
. IRB_DBPREFIX ."categories`
WHERE `site`='daterussianbride'
"
);
while($row = mysql_fetch_assoc($res))
{
$res2 = mysqlQuery("SELECT `girl`
FROM `"
.IRB_DBPREFIX."daterussianbride`
WHERE `cat` = "
.$row['id']."
ORDER BY RAND()
LIMIT 1
"
);
$row2 = mysql_fetch_assoc($res2);

Спустя 59 минут, 11 секунд (2.04.2011 - 17:24) Trianon написал(а):
Цитата
8 категорий всего, из них надо взять для каждой категории по 1 девушке случайной, которая относится к этой категории.


Примерно так я и предполагал.

Слово "случайной" гасит всю постановку задачи накорню.
SQL-запросы ориентированы на получение детерминированных ответов, которые не меняются от попытки к попытке.
Соответственно, любая рандомизация естественна только на уровне приложения, а не на уровне запроса к БД. Хотя последнее время разработчики СУБД (очевидно под влиянием сиюминутных потребностей web-разработчиков) такие средства добавлять пытаются. Понятно, что вразрез самой концепции реляционной БД, добавления получаются достаточно кривыми.


На самом деле, если рассматривать целевое (а не меркантильное) назначение практически любого сайта, то без этих рандомных выборок можно обойтись.

Спустя 11 минут, 58 секунд (2.04.2011 - 17:36) alex12060 написал(а):
Trianon

Ну почему. Ему, как я понял, нужно вытащить 8 красавиц, как бы на показ, поэтому, тут рандом нужен.
Но я многое слышал об ORDER BY RAND() и о + и о - (больше о минусах)

Поэтому, хочу у Вас поинтересоваться, стоит ли делать выборку с помощью данной вещи? Может просто ,на уровне пхп ( shuffle() ) сделать вывод рандомным, али же желательней отсортировать данные еще при выборке, дабы не усложнять программный код?

*** сорри за офтоп ***

Спустя 59 минут, 39 секунд (2.04.2011 - 18:35) Trianon написал(а):
Цитата

Ну почему. Ему, как я понял, нужно вытащить 8 красавиц, как бы на показ, поэтому, тут рандом нужен.

Вот об этом я и дышу.

Если из 20 равнозначных, скажем так, красавиц, скрипт выберет 8 - остальные 12 обидятся.
"Обидится" также и посетитель сайта, поскольку информации об этих 12-ти его лишат.

Но задача есть задача. Хоть и меркантильная.
Решать её можно по разному.
Можно решить всё на уровне приложения, как Вы предложили. Но для этого потребуется выбирать все строки, и хорошо если их там только 12 лишних.
А если 12 тысяч?
Можно сформулировать задачу так, что на уровне SQL она станет детерминированной.
Можно, например, выбрать данные группирующим запросом по агрегатной функции от случайного хеширующего фактора (который определить на уровне php.)

$hash = microtime(1);
SELECT n2.*
(
SELECT cat, MAX(CRC32(CONCAT(id , '$hash'))) AS det
FROM nominants
GROUP BY cat
) AS n1 JOIN nominants n2 ON n1.cat, = n2.cat
AND n1.det = CRC32(CONCAT(n2.id , '$hash'))



PS. inpost, тоже сорри за оффтоп.

Спустя 41 минута, 27 секунд (2.04.2011 - 19:17) inpost написал(а):
Спасибо Sergeisу, немного подправил запрос и решил таким образом. Вроде всё правильно работает, чуть позже на днях буду замерять запросы, что эфективнее в итоге получится. А пока сам запрос:
SELECT `cat` , `girl` 
FROM (
SELECT `cat` , `girl`
FROM `dat_daterussianbride`
WHERE `cat`
IN ( 1, 2, 3, 4, 5, 6, 7, 8 )
ORDER BY RAND()
)
`your_sql`
GROUP BY `cat`
LIMIT 8


_____________
Обучаю веб-программированию качественно и не дорого: http://school-php.com
Фрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.