Answer the question
In order to leave comments, you need to log in
How to select unique records, make groupBy work after union?
There is a table (chat) id | from | to | text | datetime
And related user
Tried through union, but duplicates are removed only before union:
public function getSended(){
return $this->hasMany(Chat::className(),['from'=>'id']);
}
public function getReceived(){
return $this->hasMany(Chat::className(),['to'=>'id']);
}
public function getDialogs(){
return $this->getSended()->select('id,to,to as userid')->groupBy('userid')->union($this->getReceived()->select('id,from,from as userid')->groupBy('userid'))->with('toUser');
}
SELECT COUNT(*) FROM ((SELECT `id`, `to`, `to` AS `userid` FROM `chat` WHERE `from`=1 GROUP BY `userid`) UNION ( SELECT `id`, `from`, `from` AS `userid` FROM `chat` WHERE `to`=1 GROUP BY `userid` )) `c`
public function getDialogs(){
$ids = $this->getSended()->select('to as userid')->groupBy('userid')->union($this->getReceived()->select('from as userid')->groupBy('userid'))->asArray()->all();
return self::find()->andWhere(['id'=>ArrayHelper::getColumn($ids,'userid')])->groupBy('id');
}
Answer the question
In order to leave comments, you need to log in
That is, in fact, you have a table of messages between users and you need to select the last message within each dialog.
I see three solutions here:
Option 1.
If we assume that the last message is a message with a large identifier, then all the last messages in the dialog can be obtained like this
SELECT
*
FROM
chat
LEFT JOIN (
SELECT
max(id) AS message_id,
IF (`to` = 1, `from`, `to`) AS `collocutor_id`
FROM
chat
GROUP BY
`collocutor_id`
) AS m ON chat.id = m.message_id
WHERE
m.message_id IS NOT NULL
SELECT
*
FROM
chat
WHERE
id IN (
SELECT
max(id) AS message_id
FROM
chat
GROUP BY
IF (`to` = 1, `from`, `to`)
)
SELECT
chat.*
FROM
chat
LEFT JOIN (
SELECT
max(datetime) AS datetime,
IF (`to` = 1, `from`, `to`) AS `collocutor_id`
FROM
chat
GROUP BY
`collocutor_id`
) AS m ON (
m.`collocutor_id` = chat.`to`
OR m.`collocutor_id` = chat.`from`
)
AND chat.datetime < m.datetime
WHERE
m.datetime IS NULL
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question