Задать вопрос
@sergey_zhuravlev_89

Как выбрать с помощью DISTINCT в yii2 (AR)?

Добрый вечер.
Подскажите как осуществить выборку в Yii2 c DISTINCT таким образом, чтобы я могу получить значение не только тех полей, которые перечислены для distinct, но и любых других?
К примеру, у меня имеется следующий запрос:
$model = User::find()
    ->select( ['sender_id', 'recipient_id'] )
    ->distinct()
    ->all()

при такой выборе я получаю только уникальные строки в БД с полями sender_id и recipient_id, но там ведь есть еще другие поля. Как мне их получить таким образом, чтобы они не попали под DISTINCT? Пытался добавить их так addSelect но в таком случае distinct и их затрагивает.

И ещё второй вопрос! К примеру, в таблице у меня имеется две строчки вот с такими ID:
sender_id = 1 | recipient_id = 2
sender_id = 2 | recipient_id = 1

И вообще таких парных строк может быть неограниченное количество. Так вот, можно ли как то задать distinct таким образом, чтобы такие парные строки считались за одну? И получить именно ту строку у которой первичный ключ больше
  • Вопрос задан
  • 3576 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
qonand
@qonand
Software Engineer
при такой выборе я получаю только уникальные строки в БД с полями sender_id и recipient_id, но там ведь есть еще другие поля.

Distinct не возвращает уникальные СТРОКИ, он возвращает уникальные ЗНАЧЕНИЕ указанных столбцов, в Вашем случае - уникальные сочетания значений sender_id и recipient_id.

И вообще таких парных строк может быть неограниченное количество. Так вот, можно ли как то задать distinct таким образом, чтобы такие парные строки считались за одну?

Вы бы лучше описали какую задачу хотите решить и какая структура БД, а то складывается ощущение что Вы вообще не с того краю подходите к ее решению. Вы пытаетесь вывести список собеседников пользователя? или что?

UPD по результатам обсуждения: Вашу задачу можно решить в самом простом варианте так:
$expression = new \yii\db\Expression('id IN (SELECT MAX(id) FROM messages WHERE `sender_id` = :user_id OR `recipient_id` = :user_id, GROUP BY IF (`sender_id` = :user_id, `recipient_id`, `sender_id`))',[':user_id' => 3]);
$models = Messages::find()->where($expression);


Но вообще я думаю имеет смысл создать отдельную таблицу, хранящую информацию о диалогах
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@AlikDex
при такой выборе я получаю только уникальные строки в БД с полями sender_id и recipient_id, но там ведь есть еще другие поля. Как мне их получить таким образом, чтобы они не попали под DISTINCT?

Это противоречие. Вам или уникальные, или другие фильтры использовать.

И вообще таких парных строк может быть неограниченное количество. Так вот, можно ли как то задать distinct таким образом, чтобы такие парные строки считались за одну?

Это как? Как две разные строки считать одинаковыми?! Головой подумайте!

По второму вопросу что-то вроде:
SELECT `sender_id`, `recipient_id`
FROM `table`
GROUP BY (`sender_id`, `recipient_id`)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы