我的mysql表看起来像:
user_messages
id | user_id | phone_number |消息|方向| created_at
用户
id |名称
我想'用'user_messages'分组两次,然后UNION结果。我为什么要这样做?因为user_id有时会有一个有效的用户ID(除了'-1'之外),然后我按它分组,如果它有-1,那么按phone_number分组。
我还想将结果与users表一起使用以获取用户名,以防user_id设置为有效用户
我差不多完成了查询,但问题是:
- 我希望结果让group by得到的记录成为最新记录,这意味着,最大的created_at值
select * from (
(
select *, count(*) as `total` from
(select `user_id`, `message`, `created_at`, `phone_number`,`direction` from `users_messages` where `user_id` != -1 order by `created_at` desc)
as `t1` group by `user_id`
)
union
(
select *, count(*) as `total` from
(select `user_id`, `message`, `created_at`, `phone_number`,`direction` from `users_messages` where `user_id` = -1 order by `created_at` desc)
as `t2` group by `phone_number`
)
) as `t3`
left join (select `id`,`name` from `users`) as `t4` on `t3`.`user_id` = `t4`.`id` order by `created_at` desc
这让我得到的结果是没有按created_at DESC
排序 更新
该查询实际上在我的本地计算机上工作,但不在生产服务器上。在我的本地计算机中,我有5.5.42 - Source distribution
和服务器Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper
......可能出错了什么?
在本地机器中,它正确地返回max max_at,但在服务器中它返回为记录分组创建的FIRST
答案 0 :(得分:1)
Since you're grouping by user_id and phone_number, you can't keep message or direction. Add a max function for created_at in each subquery. I think this would work.
select * from (
(
select user_id
,'' as phone_number
,max('created_at') as 'created_at'
,count(*) as `total` from
(select `user_id`
,`created_at`
from `users_messages`
where `user_id` != -1)
as `t1` group by `user_id`
)
union
(
select '' as user_id
,phone_number
,max('created at') as 'created_at'
,count(*) as `total` from
(select `created_at`
,`phone_number'
from `users_messages`
where `user_id` = -1)
as `t2` group by `phone_number`
)
) as `t3`
left join (select `id`,`name` from `users`) as `t4`
on `t3`.`user_id` = `t4`.`id`
order by `created_at` desc
答案 1 :(得分:1)
这样的事情应该有效:
SELECT s.`user_id`, um.`phone_number`, s.msgCount
, um.`message`, um.`created_at`, um.`direction`
, u.`name` AS userName
FROM (
SELECT `user_id`, IF(`user_id` = -1, `phone_number`, '') AS altID, MAX(`created_at`) AS lastCreatedAt, COUNT(*) AS msgCount
FROM `users_messages`
GROUP BY user_id, altID
) AS s
INNER JOIN `users_messages` AS um
ON s.user_id = um.user_id
AND s.altID = IF(um.`user_id` = -1, um.`phone_number`, '')
AND s.lastCreatedAt = um.created_at
LEFT JOIN `users` AS u
ON s.user_id = u.user_id
ORDER BY um.created_at DESC
;
s
子查询获取每个用户和无用户电话号码的摘要信息;计算的摘要信息包括以下使用的最新created_at
值.... um
的加入获取其上次邮件的行数据(通过在加入条件中包含lastCreatedAt
的{{1}}值)s
的最终加入用于获取已知用户的users
(并假设不会有user.name
个用户,或者这样的用户会有适当的-1
名称。)