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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SQL文で右から1文字だけ削除す...
-
割合(パーセント)を求めるに...
-
使うべきでない文字。
-
DATE型にNULLをセットするには?
-
[VBA] ADOの Clone と AddNew
-
【SQL】existsでの商演算
-
カレントレコードが無い事を判...
-
Access でレコードセレクタが押...
-
Line Inputで文字化け(助けて...
-
sqlplusの処理が途中でとまる
-
SELECTの結果で同一行を複数回...
-
SELECT文で重複せずに取得する...
-
差し込み印刷のレコード数について
-
GROUP BYを行った後に結合した...
-
レコードセット(ADO.Recordset)...
-
レコードが存在しなかった場合
-
MERGE文を単体テーブルに対して...
-
サブレンジ分割されたNDB(富士...
-
固有レコード識別子の選択とは
-
【至急】Accessでの大量データ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SQL文で右から1文字だけ削除す...
-
【MYSQL】asでリネームしてwher...
-
使うべきでない文字。
-
sum()の出力結果順に並び替えを...
-
MySQLで MAX()とGROUP BYを使う...
-
【初歩】ラジオボタンをつかっ...
-
MySQL のデータからドロップダ...
-
チェックボックスの項目をDBにi...
-
月別、販売員別の集計がわかり...
-
カウント結果を1レコードの中...
-
何にかが違うから エラーなんで...
-
SQLの集計で「全て」の合計も表...
-
割合(パーセント)を求めるに...
-
MySQL 副問い合わせ(IN)での...
-
LIKE述語/SQLとPHPを使った検...
-
MySQLにて特定レコードのみを抽...
-
MySQLで2つのテーブルのデータ...
-
初心者Mysqlの関数のsubstring...
-
サブクエリ内で INNER JOIN は
-
条件検索の方法について
おすすめ情報