2017-09-14 7 views
0

私はあなたの助けが必要です。私はデバイスからのメッセージの監視を開発しようとし、SQLクエリでいくつかの問題に直面しています。私は4つのテーブルを持つDBを持っています:デバイス - メッセージ - レベル - アクション。デバイス監視のMySQLクエリ

デバイス: id、name; actions: id、name; レベル: id、action_id、msgcount; メッセージ: id、action_id、device_id;

アイデアは、各デバイスがさまざまなアクションについてメッセージを送信していることです。このメッセージは 'messages'テーブルに登録されています。各アクションには、このレベルを取得するためのメッセージの数に応じてレベルの量が異なります。私は登録されたメッセージを数え、UIの進捗状況を次のレベルと追加情報に表示したい。メッセージプロデバイス

しかし、問題のトップレベルが既に受け取っている場合、このアクションはこれ以上のリストに示されているということではありません -

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:私は次のクエリを使用します。しかしこの場合、最後に受け取ったレベル(最大)とメッセージの合計数を表示したいと思います。誰かが私を助けてくれますか?

また、私の質問をどのように忠実に伝えるためのアドバイスをいただければ幸いです。

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

それはより多くのレベルを持っていないので、表現、アクション42についての情報はありません。

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  | 
|------------|---------|----------|-----------|--------------|--------------| 
|  42 | 4 | 1  | 3  |  low  | connection | 
|  51 | 1 | 2  | 3  | start  | stop service | 
|------------|---------|----------|-----------|--------------|--------------| 

を、私はそれが可能だ願っています:)

+0

4つのテーブルすべてのデータを使用して、期待される出力と現在の出力を共有できますか。 –

+0

@HatimStovewalaこんにちは、上記の例をいくつか追加しました – Lev

+0

メッセージテーブルに重複行があるのはなぜですか?私はデバイスID 5のために、アクションIDが42の4つの行があることを確認できます。 –

答えて

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) 

は、ハテムをありがとう!

+0

おかげでね!それは他の方法ラウンドを助けてうれしい。 –

1

はこれを試してみてください: は、私は、デバイス5のために、この場合には、次の結果を得るためにクエリを変更します。これはあなたに現在のレベルを与えるでしょう。

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;