SQL语句构造:选择唯一记录

时间:2014-01-04 01:38:15

标签: mysql sql select group-by unique

我目前有一个用户表,以及他们何时连接到设备(例如Wifi路由器)。

+-------------+-----------+---------+------------+---------------------+
| location_id | device_id | user_id | dwell_time | date                |
+-------------+-----------+---------+------------+---------------------+
|          14 |         1 |       1 |  27.000000 | 2014-01-04 00:51:12 |
|          15 |         2 |       1 |  12.000000 | 2014-01-04 01:08:56 |
|          16 |         1 |       1 |  12.000000 | 2014-01-04 01:09:26 |
|          17 |         2 |       1 | 318.000000 | 2014-01-04 01:09:38 |
|          18 |         1 |       2 |  20.000000 | 2014-01-04 01:30:03 |
|          19 |         2 |       3 |  20.000000 | 2014-01-04 01:30:03 |
+-------------+-----------+---------+------------+---------------------+

我需要编写一个查询标题“获取最新用户连接”。

基本上,它需要浏览上面显示的历史表,并为每个用户选择最新记录(基于日期)并显示它。在上面的示例中,结果应为:

+-------------+-----------+---------+------------+---------------------+
| location_id | device_id | user_id | dwell_time | date                |
+-------------+-----------+---------+------------+---------------------+
|          17 |         2 |       1 | 318.000000 | 2014-01-04 01:09:38 |
|          18 |         1 |       2 |  20.000000 | 2014-01-04 01:30:03 |
|          19 |         2 |       3 |  20.000000 | 2014-01-04 01:30:03 |
+-------------+-----------+---------+------------+---------------------+

有人可以帮我写一个执行此操作的SQL语句吗?

3 个答案:

答案 0 :(得分:2)

假设user_iddate的组合在表格中是唯一的,您可以

SELECT
  tablename.*
FROM tablename
  INNER JOIN (
    SELECT user_id, MAX(`date`) AS maxdate
    FROM tablename
    GROUP BY user_id
  ) AS selector
  ON tablename.user_id=selector.user_id AND tablename.`date`=selector.maxdate

答案 1 :(得分:1)

select *
 from users
 inner join (select user_id,max(date) as maxdate
             from users
             group by user_id)T1
 on T1.user_id = users.user_id
 AND T1.maxdate = users.date

或者如果您不想拥有子查询,可以像下面的查询一样使用@variables

SELECT location_id,device_id,user_id,dwell_time,date,
       IF(@prevUserId IS NULL OR @prevUserId != user_id,@row:=1,@row:=@row+1) as row,
       @prevUserId := user_id
FROM users
HAVING row = 1
ORDER BY user_id,date DESC

这是sqlFiddle

答案 2 :(得分:0)

试试这个:

SELECT u.location_id, u.device_id, u.user_id, u.dwell_time, u.datec
FROM (SELECT u.location_id, u.device_id, u.user_id, u.dwell_time, u.date 
      FROM users u ORDER BY u.user_id, u.date DESC
     ) A 
GROUP BY u.user_id

SELECT u.location_id, u.device_id, u.user_id, u.dwell_time, u.date
FROM users u
INNER JOIN (SELECT u.user_id, MAX(u.date) AS latestDate 
            FROM users u GROUP BY u.user_id
           ) A ON u.user_id = A.user_id AND A.latestDate = u.date