mysql查询获取每个类别的最新记录

时间:2016-06-08 08:35:00

标签: mysql sql

我有2个表设备和位置。我需要结果像deviceid最新的5条记录,其中admin id。作为json格式 表格如下: 设备表:

    +-----------------------+
    | id |device_id|adminid |
    +-----------------------+
    |  1 |eefdcdfs | admin1 |
    |  2 |ffsdxwe2 | admin1 |
    |  3 |aaqw35ds | admin2 |
    |  4 |grfdr23f | admin2 |
    |  5 |etdhy79e | admin3 |
    +-----------------------+

位置表:

    +-----------------------------------------------------------------+
    | lid|lat       |long      |time               |deviceid |adminid |
    +----+----------+----------+-------------------+---------+--------+
    |  1 |17.4425358|78.3922061|2016-06-08 12:23:24|eefdcdfs | admin1 |
    |  2 |17.4425358|78.3922061|2016-06-08 12:45:24|eefdcdfs | admin1 |
    |  3 |17.4425358|78.3922061|2016-06-08 11:56:24|eefdcdfs | admin1 |
    |  4 |17.4425358|78.3922061|2016-06-08 12:53:24|eefdcdfs | admin1 |
    |  5 |17.4425500|78.3922342|2016-06-08 12:53:34|ffsdxwe2 | admin1 |
    |  6 |17.4425342|78.3922546|2016-06-08 11:55:34|ffsdxwe2 | admin1 |
    |  7 |17.4425562|78.3922657|2016-06-08 12:23:34|ffsdxwe2 | admin1 |
    |  8 |17.4425223|78.3922675|2016-06-08 12:12:34|ffsdxwe2 | admin1 |
    |  9 |17.4424856|78.3922307|2016-06-08 12:56:48|aaqw35ds | admin2 |
    | 10 |17.4425453|78.3922087|2016-06-08 13:08:30|grfdr23f | admin2 |
    | 11 |17.4425472|78.3922294|2016-06-08 13:15:54|etdhy79e | admin3 |
    +----+----------+----------+-------------------+---------+--------+

预期结果:

    +-----------------------------------------------------------------+
    | lid|lat       |long      |time               |deviceid |adminid |
    +----+----------+----------+-------------------+---------+--------+
    |  4 |17.4425358|78.3922061|2016-06-08 12:53:24|eefdcdfs | admin1 |
    |  2 |17.4425358|78.3922061|2016-06-08 12:45:24|eefdcdfs | admin1 |
    |  1 |17.4425358|78.3922061|2016-06-08 12:23:24|eefdcdfs | admin1 |
    |  3 |17.4425358|78.3922061|2016-06-08 11:56:24|eefdcdfs | admin1 |
    |  5 |17.4425500|78.3922342|2016-06-08 12:53:34|ffsdxwe2 | admin1 |
    |  7 |17.4425562|78.3922657|2016-06-08 12:23:34|ffsdxwe2 | admin1 |
    |  8 |17.4425223|78.3922675|2016-06-08 12:12:34|ffsdxwe2 | admin1 |
    |  6 |17.4425342|78.3922546|2016-06-08 11:55:34|ffsdxwe2 | admin1 |
    +----+----------+----------+-------------------+---------+--------+

我试过了:

    select deviceid,CONCAT('[',CAST(lat AS CHAR ),',',CAST(long AS
    CHAR ),'],') json from locations WHERE 
    admin_id='admin1' 
    AND `time` > DATE_SUB(NOW(), 
    INTERVAL 3 HOUR) ORDER BY time DESC limit 10;

2 个答案:

答案 0 :(得分:0)

这是我的程序中使用的mysql查询。使用join连接两个表 Distinct将避免复制。

qry=Select distinct * from  tbl_1 join tbl_2 on tbl_1 .Som_Id =tbl_2 .S_Id  order by DATE1"; 

这是一个仅供参考的示例。通过进行一些更改,您可以实现结果。

答案 1 :(得分:0)

执行此操作的一种方法是使用变量。执行子查询以获取您感兴趣的可能行,按时间降序排序。为每个设备ID相同的计数器添加1。将这些结果用作子查询,并返回计数器为5或更小的那些结果。

这样的事情: -

SELECT lid,
    lat,
    `long`,
    `time`,
    deviceid,
    adminid
FROM
(
    SELECT lid,
        lat,
        `long`,
        `time`,
        deviceid,
        adminid,
        @cnt:=IF(@deviceid = deviceid, @cnt + 1, 1) AS cnt,
        @deviceid := deviceid
    FROM
    (
        SELECT locations.lid,
            locations.lat,
            locations.`long`,
            locations.`time`,
            locations.deviceid,
            locations.adminid
        FROM devices
        INNER JOIN locations
        ON devices.device_id = locations.deviceid
        WHERE locations.adminid = 'admin1' 
        AND locations.`time` > DATE_SUB(NOW(), INTERVAL 3 HOUR)
        ORDER BY  locations.deviceid, locations.time DESC
    ) sub0
    CROSS JOIN 
    (
        SELECT @cnt:=0, @deviceid:=''
    ) sub1
) sub2
WHERE cnt <= 5

修改

另一种方法是使用和滥用GROUP_CONCAT语句来获取每个设备的所有时间,然后SUBSTRING_INDEX获得第5次(如果少于5次,它将获得最后一个,在这种情况下是好的),以及然后将其加入到您的表中以获取具有适当时间的记录: -

SELECT locations.lid,
        locations.lat,
        locations.`long`,
        locations.`time`,
        locations.deviceid,
        locations.adminid
FROM devices
INNER JOIN locations
ON devices.device_id = locations.deviceid
INNER JOIN      
(
    SELECT locations.deviceid,
        GROUP_CONCAT(locations.`time` ORDER BY locations.time DESC) AS times
    FROM devices
    INNER JOIN locations
    ON devices.device_id = locations.deviceid
    WHERE locations.adminid = 'admin1' 
    AND locations.`time` > DATE_SUB(NOW(), INTERVAL 3 HOUR)
    GROUP BY locations.deviceid
) sub0
ON locations.deviceid = sub0.deviceid
AND locations.`time` >= SUBSTRING_INDEX(SUBSTRING_INDEX(sub0.times, ',', 6), ',', -1)
WHERE locations.adminid = 'admin1'