通过函数mysql查找模式而不是MAX / AVG

时间:2018-11-30 08:56:01

标签: mysql group-by average

我正在使用以下查询,但是在测试时发现,MODE比考虑使用MAX会给我更好的结果。

SELECT MAX(rssi) AS rssii,beacon,receiver  
FROM readings 
WHERE created_datetime BETWEEN  '2018-11-29 09:46:10'  AND  '2018-11-29 10:58:50'
GROUP BY beacon,receiver;

我只能选择我指的是没有任何分组依据的特定列,而获得RSSI的模式,

SELECT rssi,count(*) as occurs
FROM readings
GROUP BY `rssi` order by occurs desc
LIMIT 1;

但是我发现每个小组都很难做到这一点,

预期结果格式

+-------+-----------+-----------+
| rssii | beacon    |   receiver|
+-------+-----------+-----------+
|   -42 |       AAA |       XXX |
|   -49 |       AAA |       YYY |
|   -49 |       AAA |       ZZZ |
|   -44 |       BBB |       XXX |
|   -54 |       BBB |       YYY |
|   -52 |       BBB |       ZZZ |
|   -49 |       CCC |       XXX |
|   -42 |       CCC |       YYY |
|   -57 |       CCC |       ZZZ |
+-------+---------+-------------+

任何人都可以帮忙。...

2 个答案:

答案 0 :(得分:1)

您可以通过首先获取每个信标/接收器对rssi个值的计数来解决问题,如下所示:

SELECT beacon, receiver, rssi, COUNT(*) as occurs
FROM readings
GROUP BY beacon, receiver, rssi

然后查找每个信标/接收器对的模式,您可以将其用作子查询,并将其加入最大occurs值的列表中:

SELECT beacon, receiver, rssi, occurs 
FROM (SELECT beacon, receiver, rssi, COUNT(*) as occurs
      FROM readings
      GROUP BY beacon, receiver, rssi) r1
JOIN (SELECT beacon, receiver, rssi, MAX(occurs)
      FROM (SELECT beacon, receiver, rssi, COUNT(*) as occurs
            FROM readings
            GROUP BY beacon, receiver, rssi) r2
      GROUP BY beacon, receiver, rssi) r3
  ON r3.beacon = r1.beacon AND r3.receiver = r1.receiver AND r3.rssi = r1.rssi

请注意,如果信标/接收器对具有多个模式值,则将为您提供所有这些值。您可能需要在初始选择中使用MAX(rssi),并使用GROUP BY beacon, receiver将结果限制为每对一个rssi值,即

SELECT beacon, receiver, MAX(rssi), occurs 
FROM (SELECT beacon, receiver, rssi, COUNT(*) as occurs
      FROM readings
      GROUP BY beacon, receiver, rssi) r1
JOIN (SELECT beacon, receiver, rssi, MAX(occurs)
      FROM (SELECT beacon, receiver, rssi, COUNT(*) as occurs
            FROM readings
            GROUP BY beacon, receiver, rssi) r2
      GROUP BY beacon, receiver, rssi) r3
  ON r3.beacon = r1.beacon AND r3.receiver = r1.receiver AND r3.rssi = r1.rssi
GROUP BY beacon, receiver

答案 1 :(得分:1)

就像在许多其他复杂问题中一样,动态编程可轻松解决这一问题,并且也易于理解。

首先在Mysql中声明两个临时变量

set @mc1 = '', @rc1 = '';

然后将它们用作临时占位符并遍历结果集。

select rssi,cr, mc,rc, @mc1:=mc,@rc1:=rc from (
SELECT rssi, count(rssi) cr,beacon AS mc,receiver AS rc
FROM readings
WHERE created_datetime BETWEEN  '2018-11-29 09:46:10'  AND  '2018-11-29 10:58:50'
GROUP BY readings.beacon ,readings.receiver, rssi order by mc,rc,cr desc
) p where (mc != @mc1 or rc != @rc1)

我得到了想要的东西

+------+-----+-----+-----+----------+----------+
| rssi | cr  | mc  | rc  | @mc1:=mc | @rc1:=rc |
+------+-----+-----+-----+----------+----------+
|  -53 | 127 | AAA | XXX    | AAA   | XXX |
|  -55 | 109 | AAA | YYYY   | AAA   | YYYY |
|  -52 | 194 | AAA | ZZZ    | AAA   | ZZZ |
|  -53 | 112 | BBB | XXX    | BBB   | XXX |
|  -48 | 218 | BBB | YYYY   | BBB   | YYYY |
|  -64 |  72 | BBB | ZZZ    | BBB   | ZZZ |
|  -47 | 151 | CCC| XXX     | CCC   | XXX |
|  -38 | 204 | CCC| YYYY    | CCC   | YYYY |
|  -53 | 120 | CCC| ZZZ     | CCC   | ZZZ |
|  -54 | 152 | DDD| XXX     | DDD   | XXX |
|  -62 |  80 | DDD| YYYY    | DDD   | YYYY |
|  -56 | 138 | DDD| ZZZ     | DDD   | ZZZ |
+------+-----+-----------+----------+