Проблема с DISTINCT! - PullRequest
       14

Проблема с DISTINCT!

2 голосов
/ 05 октября 2009

Вот мой запрос:

SELECT 
DISTINCT `c`.`user_id`,
`c`.`created_at`,
`c`.`body`,
(SELECT COUNT(*) FROM profiles_comments c2 WHERE c2.user_id = c.user_id AND c2.profile_id = 1) AS `comments_count`,
`u`.`username`,
`u`.`avatar_path` 
FROM `profiles_comments` AS `c` INNER JOIN `users` AS `u` ON u.id = c.user_id 
WHERE (c.profile_id = 1) ORDER BY `u`.`id` DESC;

Это работает. Проблема, однако, со словом DISTINCT. Насколько я понимаю, в c.user_id следует выбирать только одну строку.

Но я получаю даже 4-5 строк с одним и тем же столбцом c.user_id. Где проблема?

Ответы [ 5 ]

9 голосов
/ 05 октября 2009

на самом деле, DISTINCT не ограничивается 1 столбцом, в основном, когда вы говорите:

ВЫБЕРИТЕ DISTINCT a, b

То, что вы говорите, «дайте мне отличное значение a и b вместе взятых» .. точно так же, как многостолбцовый индекс UNIQUE

6 голосов
/ 05 октября 2009
Отличное значение

гарантирует, что ВСЕ значения в предложении select являются уникальными, а не только user_id. Если вы хотите ограничить результаты отдельными user_ids, вы должны сгруппировать по user_id.

Возможно, что вы хотите:

SELECT 
`c`.`user_id`,
`u`.`username`,
`u`.`avatar_path`,
(SELECT COUNT(*) FROM profiles_comments c2 WHERE c2.user_id = c.user_id AND c2.profile_id = 1) AS `comments_count` 
FROM `profiles_comments` AS `c` INNER JOIN `users` AS `u` ON u.id = c.user_id 
WHERE (c.profile_id = 1) 
GROUP BY `c`.`user_id`,
`u`.`username`,
`u`.`avatar_path`
ORDER BY `u`.`id` DESC;
2 голосов
/ 05 октября 2009

DISTINCT работает на уровне строк, а не только на уровне столбцов

Если вы хотите, чтобы DISTiNCT составлял только один столбец, вам придется объединять оставшиеся возвращаемые столбцы (MIN, MAX, SUM, AVG и т. Д.)

SELECT DISTINCT (Name), Min (ID)
From MyTable
1 голос
/ 05 октября 2009

Вы неправильно поняли. Модификатор DISTINCT применяется ко всей строке - он гласит, что в наборе результатов не будет возвращено две одинаковые строки.

Глядя на ваш SQL, какое значение из нескольких доступных вы ожидаете увидеть возвращенным в столбце созданный_каталог (например)? Было бы невозможно предсказать результаты запроса в письменном виде.

Кроме того, вы дважды используете profile_comments в вашем SELECT. Похоже, вы пытаетесь подсчитать, сколько раз каждый пользователь прокомментировал. Если это так, то вы хотите использовать AGGREGATE-запрос, сгруппированный по user_id и включающий только те столбцы, которые однозначно идентифицируют пользователя вместе с COUNT комментариев:

ВЫБРАТЬ user_id, COUNT (*) ОТ profile_comments WHERE profile_id = 1 GROUP BY user_id

Вы можете добавить объединение для пользователей, чтобы получить имя пользователя, если хотите, но, по логике вещей, ваш результирующий набор не может включать другие столбцы из profile_comments и по-прежнему генерировать только одну строку для user_id, если эти столбцы также не агрегированы каким-либо образом:

ВЫБРАТЬ user_id, MIN (созданный_at) AS Самый ранний, MAX (созданный_at) AS Самый последний, COUNT (*) ОТ profile_comments WHERE profile_id = 1 GROUP BY user_id

1 голос
/ 05 октября 2009

Distinct будет пытаться вернуть только уникальные строки, он не будет возвращать только 1 строку на идентификатор пользователя в вашем примере.

http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...