MySQL查询设备监控

时间:2017-09-14 19:42:14

标签: mysql

我需要你的帮助。我尝试开发来自设备的消息监控,并面临SQL查询的一些问题。我有4个表的数据库:设备 - 消息 - 级别 - 操作。

  

设备: id,name;   操作: id,name;   级别: id,action_id,msgcount;   消息: id,action_id,device_id;

想法是每个设备发送有关不同操作的消息。此消息在“消息”表中注册。每个操作都有不同的级别,其中包含要获得此级别的消息数。我想计算已注册的消息并在UI进度中显示到下一级别和som additioonal信息。我使用以下查询:

select
   mpd.action_id,
   mpd.total,
   lvl.id as lvl_id,
   lvl.msgcount purpose,
   lvl.name as level_name,
   act.name as action

from
   (select
       mes.action_id,
       count(1) total
    from
       messages mes,
       devices dev
    where
       mes.device_id=dev.id
       and dev.id=5
       and mes.action_id not in(select
                                    t.action_id
                                from
                                    messages t
                                where
                                    mes.device_id=t.device_id
                                    and t.date > CURDATE())
    group by
       mes.action_id) mpd,
    actions act,
    levels lvl

where
    mpd.action_id = act.id
    and mpd.action_id = lvl.action_id
    and lvl.msgcount = (SELECT
                            MIN(bad.msgcount)
                        FROM
                            levels lv
                        WHERE
                            lv.msgcount > mpd.total
                            and lv.action_id = mpd.action_id)

* mpd - messages pro device

但问题是如果顶层已经收到此动作,则列表中不再显示。但在这种情况下,我想显示最后收到的级别(最大)和消息总数。有人可以帮助我。

如果您提供一些建议如何改进我的查询,我将非常感激。

    devices
|------|---------|
|  id  |  name   |
|------|---------|
|   3  | RH-SW-12|
|   5  | HRS-PR  |
|   6  | PRS-PR  |
|------|---------|

             levels
|------|-----------|----------|--------|
|  id  | action_id | msgcount |  name  |
|------|-----------|----------|--------|
|  1   |    42     |    3     |  low   |
|  2   |    51     |    3     |  start |
|  3   |    51     |    7     | medium |
|  4   |    51     |    15    |  hight |
|------|-----------|----------|--------|

        actions
|------|--------------|
|  id  |     name     |
|------|--------------|
|  42  | connection   |
|  51  | stop service |
|------|--------------|


          messages
|------|-------------|------------|----------------|
|  id  |  action_id  |  device_id |  date-time     |
|------|-------------|------------|----------------|
|  1   |     42      |      3     |14.09.2017 08:51|
|  2   |     42      |      5     |14.09.2017 13:08|
|  3   |     42      |      5     |14.09.2017 16:30|
|  4   |     42      |      5     |15.09.2017 07:43|
|  5   |     51      |      3     |15.09.2017 07:50|
|  6   |     51      |      3     |15.09.2017 10:22|
|  7   |     51      |      3     |15.09.2017 15:11|
|  8   |     51      |      3     |15.09.2017 18:48|
|  9   |     51      |      3     |15.09.2017 19:03|
|  10  |     51      |      5     |15.09.2017 19:18|
|  11  |     42      |      5     |15.09.2017 21:33|
|------|-------------|------------|----------------|

我的查询现在将显示设备5的以下结果:

|------------|---------|----------|-----------|--------------|--------------|
| action_id  |  total  |  lvl_id  |  purpose  |  level_name  |  action      |
|------------|---------|----------|-----------|--------------|--------------|
|      51    |    1    |    2     |    3      |    start     | stop service |
|------------|---------|----------|-----------|--------------|--------------|

没有关于动作42的信息,因为它没有更多级别。最后一级是“低”并达到了。 我想修改查询以获得设备5的下一个结果:

|------------|---------|----------|-----------|--------------|--------------|
| action_id  |  total  |  lvl_id  |  purpose  |  level_name  |  action      |
|------------|---------|----------|-----------|--------------|--------------|
|      42    |    4    |    1     |    3      |     low      |  connection  |
|      51    |    1    |    2     |    3      |    start     | stop service |
|------------|---------|----------|-----------|--------------|--------------|

我希望有可能:)

2 个答案:

答案 0 :(得分:1)

试试这个。这将为您提供当前水平。

SELECT 
    *
FROM
    devices d,
    actions a,
    (SELECT 
        device_id, action_id, COUNT(1) AS count
    FROM
        messages
    GROUP BY device_id , action_id) m,
    levels l
WHERE
    d.id = m.device_id
        AND a.id = m.action_id
        AND l.action_id = a.id
        AND m.count >= l.msgcount
        AND d.id = 5;

答案 1 :(得分:1)

有时与合适的人进行讨论有助于从另一方面审视问题。在尝试使用来自@HatimStovewala的答案的不同变体时,我找到了正确的解决方案:

SELECT
    *
FROM
    (SELECT 
        device_id, action_id, COUNT(1) AS count
    FROM
        messages
    WHERE 
        device_id = 5
    GROUP BY device_id , action_id) tmp,
    levels lvl
WHERE
    lvl.action_id = tmp.action_id
  and lvl.msgcount = (SELECT 
                        CASE COALESCE(MIN(msgcount),0) WHEN 0 THEN (SELECT MAX(msgcount) FROM levels WHERE action_id = tmp.action_id) ELSE MIN(repetitions) END AS rep
                      FROM
                        levels
                      WHERE
                        action_id=tmp.action_id
                        and msgcount >= tmp.count)

谢谢你,Hatim!