2017-09-14 39 views
0

我需要你的帮助。我尝试开发监视来自设备的消息并面对一些SQL查询问题。我有4个表的数据库:设备 - 消息 - 水平 - 行动。设备监控的MySQL查询

devices: id,name; 操作: id,name; 等级: id,action_id,msgcount; 消息: id,action_id,device_id;

想法是每个设备发送有关不同动作的消息。此消息在'消息'表中注册。每个动作都有不同数量的消息来获得这个级别。我想统计注册的消息并显示在用户界面进展到下一个级别和索姆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 - 消息Pro设备

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

而且我会非常感激,如果你给一些建议如何imrove我的查询。现在

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

我希望这是可能的:)

+0

你能分享一个例子,所有4个表格中的数据都有预期的输出和你现在得到的输出。 –

+0

@HatimStovewala嗨,我在上面添加了一些例子 – Lev

+0

为什么你的消息表有重复的行?我可以看到设备ID为5有4行,动作ID为42. –

回答

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!

+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;