如何从同一个表加入/联合多个结果?

时间:2017-03-02 23:14:18

标签: mysql sql

我的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

2 个答案:

答案 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名称。)