![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
ZabbixのDB(MySQL)からホスト毎の最新値を取得したいと考えております。
・Zabbix 5.0.17
・MySQL 8.0.27
下記クエリを実行するとホストかつ監視項目毎の過去全ての履歴が表示されます。
<クエリ>
SELECT
s.host,
i.name,
from_unixtime(h.clock) AS date,
h.value
FROM
items i
JOIN hosts s
ON i.hostid = s.hostid
JOIN history h
ON i.itemid = h.itemid
WHERE
s.available = 1
and
i.name like '%CPU使用率%'
ORDER BY s.host,date asc;
<クエリ実行結果>
[host,name,date,value]
host1, CPU使用率, 2021-11-18 18:56:05, 1%
host1, CPU使用率, 2021-11-18 18:59:05, 21%
host1, CPU使用率, 2021-11-18 19:02:05, 10%
host1, CPU使用率, 2021-11-18 19:05:05, 23%
host2, CPU使用率, 2021-11-18 18:56:05, 29%
host2, CPU使用率, 2021-11-18 18:59:05, 41%
host2, CPU使用率, 2021-11-18 19:02:05, 33%
host2, CPU使用率, 2021-11-18 19:05:05, 45%
上記結果から、最新日時(現在時刻を11/18 19:06とした場合)のレコードのみ抽出したいと考えております。
こうしたい場合、どういったクエリ文であれば期待する結果が得られますでしょうか。
<期待するクエリ実行結果>
[host,name,date,value]
host1, CPU使用率, 2021-11-18 19:05:05, 23%
host2, CPU使用率, 2021-11-18 19:05:03, 45%
お力添え頂けましたら幸いです。
よろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
方法は大きく2つ
1.「ホスト毎の最新時刻を取得するクエリ」を作り、INNER JOIN で最新時刻の行だけ抽出する。
2. ウィンドウ関数ROW_NUMBER() で ホスト毎に行番号を付けたクエリを作り、行番号=1 だけ抽出する。
※ ウィンドウ関数は古いMySQLでは対応していないが、8.0なら大丈夫なはず
環境が無いので詳細未確認ですが、2の例です
SELECT w.host,w.name,w.date,w.value
FROM (
SELECT
s.host,
i.name,
from_unixtime(h.clock) AS date,
h.value,
row_number() over (partitiion by s.host,i.name order by h.clock) as rno
FROM
items i
JOIN hosts s
ON i.hostid = s.hostid
JOIN history h
ON i.itemid = h.itemid
WHERE
s.available = 1
and
i.name like '%CPU使用率%'
) w
where w.rno=1
ORDER BY host,date asc;
コメントありがとうございます。
教えて頂いた構文で期待する結果が得られました!!!!
(partition部分を少し修正しております)
仰せの通り、MySQL 8からwindow関数が使えるようになった模様です。
とても参考になりました、ありがとうございました!
以下実行クエリと結果です。
SELECT w.host,w.name,w.date,w.value
FROM (
SELECT
s.host,
i.name,
from_unixtime(h.clock) AS date,
h.value,
row_number() over (partition by s.host,i.name order by h.clock desc) as rno
FROM
items i
JOIN hosts s
ON i.hostid = s.hostid
JOIN history h
ON i.itemid = h.itemid
WHERE
s.available = 1
and
i.name like '%CPU使用率%'
) w
where w.rno=1;
<クエリ実行結果>
[host,name,date,value]
host1, CPU使用率, 2021-11-20 09:10:05, 23%
host2, CPU使用率, 2021-11-20 09:10:05, 45%
(話がそれますが)
historyテーブルに約16万レコード、itemsテーブルに約1万レコード、hostsテーブルに数百レコードの状況で、上記クエリを発行するとCPU負荷が上昇します(テスト環境だと10%程)
EXPLAINの実行結果を見ると、typeがALLであったりExtraにUsing temporaryとあるので、業務で使うと致命的かなと考えています。
こちらについては「MySQLクエリ改善について ~(続)MySQLにて特定レコードのみを抽出したい~」といったタイトルで別途質問をさせて頂こうと思います。
No.2
- 回答日時:
ごめんなさい、順番が逆でした。
ただ、一番古いのを持ってきちゃうと思うので、どうしようかなぁ…ということで、DATEカラムが最大値をとるWHERE句を追加して、↓これでどうでしょう?
i.name like '%CPU使用率%'
AND MAX(`date`)
GROUP BY s.host
ORDER BY s.host,date desc
DATEのカラムにMAX関数効くのかなぁ…
追記ありがとうございます。
今回はグループ関数エラーが発生していました。
SELECT
s.host AS host,
i.name,
from_unixtime(h.clock) AS date,
h.value
FROM
items i
JOIN hosts s
ON i.hostid = s.hostid
JOIN history h
ON i.itemid = h.itemid
WHERE
s.available = 1
and
i.name like '%CPU使用率%'
and
MAX(`date`)
GROUP BY host
ORDER BY host,date desc;
<実行結果>
ERROR 1111 (HY000): Invalid use of group function
No.1
- 回答日時:
最新1件だけを取り出したいということであれば、最後を下記にしたらいかがでしょう。
ORDER BY s.host,date desc
GROUP BY s.host
検証してないので、期待値と違ったらごめんなさい。
コメント頂きありがとうございます。
試してみたところ文法エラーとなりました。
SELECT
s.host AS host,
i.name,
from_unixtime(h.clock) AS date,
h.value
FROM
items i
JOIN hosts s
ON i.hostid = s.hostid
JOIN history h
ON i.itemid = h.itemid
WHERE
s.available = 1
and
i.name like '%CPU使用率%'
ORDER BY host,date desc
GROUP BY host;
<実行結果>
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY host' at line 17
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- ノートパソコン パソコンが重い。 職場で使用しているパソコンが夏休み明けあたりから急に重くなりました。 (特定のソフ 10 2022/09/06 17:30
- ビデオカード・サウンドカード メイン機とは別に、初自作としてpcを組みました。 pcスペック cpu ryzen5 5500 グラ 1 2023/05/15 12:22
- Windows 10 インストールしたてのVirtualBoxの仮想マシンにDHCPで割り振られるIPアドレスにつきまして 1 2023/05/03 14:46
- FTTH・光回線 IPv4ネットワーク速度の改善方法 4 2023/02/11 11:55
- C言語・C++・C# 1. 仮想CPU「exmini」を使用して,「$dataからn減算する」プログラムを作成してください 2 2022/07/04 17:49
- その他(データベース) Accessフォームにて指定のフィールドの平均値を小数点第一位で表示できない 2 2022/08/30 17:19
- BTOパソコン 約2年半くらい使用しているゲーミングPCが故障したので、パソコン工房に診断を依頼した結果、異常の確認 10 2023/06/28 12:57
- 画像編集・動画編集・音楽編集 PowerDirector21 動画出力時のCPU稼働率が急に下がってしまう原因を教えてください 2 2023/03/30 20:54
- CPU・メモリ・マザーボード AMD Ryzen3700X 付属のCPUクーラー性能はいかほどか? 2 2022/05/16 21:19
- Visual Basic(VBA) ExcelからAccessのテーブルに書き込む時に時間がかかる 1 2022/10/14 20:38
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【MYSQL】asでリネームしてwher...
-
sum()の出力結果順に並び替えを...
-
SQL文で右から1文字だけ削除す...
-
SQLの集計で「全て」の合計も表...
-
使うべきでない文字。
-
チェックボックスの項目をDBにi...
-
MySQL のデータからドロップダ...
-
【初歩】ラジオボタンをつかっ...
-
Oracleでの文字列連結サイズの上限
-
GROUP BYを行った後に結合した...
-
Accessで別テーブルの値をフォ...
-
SELECTで1件のみ取得するには?
-
アクセスでレポートの1印刷内...
-
select insertで複数テーブルか...
-
Excelで、改行がある場合の条件...
-
レコードが存在しなかった場合
-
SELECTの結果で同一行を複数回...
-
GROUP BYを使ったSELECT文の総...
-
DataGridViewの内容をDBに反映...
-
ファイル書込みで一行もしくは...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SQL文で右から1文字だけ削除す...
-
【MYSQL】asでリネームしてwher...
-
使うべきでない文字。
-
割合(パーセント)を求めるに...
-
チェックボックスの項目をDBにi...
-
カウント結果を1レコードの中...
-
SQLの集計で「全て」の合計も表...
-
月別、販売員別の集計がわかり...
-
sum()の出力結果順に並び替えを...
-
MySQLで MAX()とGROUP BYを使う...
-
【初歩】ラジオボタンをつかっ...
-
何にかが違うから エラーなんで...
-
複数の表の条件でのDELETE文
-
replaceした上でwhere
-
LIKE述語/SQLとPHPを使った検...
-
今週の日曜日から土曜日までの...
-
重複が
-
MySQLにて特定レコードのみを抽...
-
MySQLで2つのテーブルのデータ...
-
phpmyadminはトリガーやIF文を...
おすすめ情報