グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



MySQLのJSON型に含まれる値でソートをかける方法 (数値・文字列・Goのtime.Time型)

MySQLのJSON型に含まれている中の値で、ソートをかける方法についてまとめたいと思います。 JSON型に変換したGoのtime.Time型をソートする方法も後半でご紹介します。

準備

まずはMySQLのコンテナとサンプルデータを準備していきます。
DockerでMySQLのコンテナをたてます。(imageはを以下のものを使用します。)

コンテナの準備ができたらコンテナでMySQLに接続します。
今回使用するMySQLのバージョンは以下の通りです。

ソート対象のサンプルデータを用意します。
timeに指定されている時間は、Goのtime.Time型をMarshalして算出した値です。
また、0001-01-01T00:00:00Zの値はtime.Time型のゼロ値です。

永続化した値を確認してみます。

JSON_EXTRACTを使用する方法

JSON_EXTRACTを使用してソートをかけてみたいと思います。
使い方の詳細についてはMySQLリファレンスマニュアルを参考にしてください。

“type”を昇順に並べ替えてみます。

“type”が1〜4で昇順にソートされたことが確認できました。
あわせて”available”にもソートをかけてみます。

同じ”type”の中で、true>falseの順番になっているので、”available”にもソートがかけられたことが確認できました。

「->」演算子を使用する方法

先ほどはJSON_EXTRACTを使用しましたが、「->」演算子を使用することもできます。 JSON_EXTRACTの省略記法なので、同様の機能を果たします。

リファレンスにも以下のような記述があります。

-> 演算子は、左側のカラム識別子とJSON ドキュメント(カラム値)に対して評価される右側のJSONパスの2つの引数で使用されるJSON_EXTRACT()関数のエイリアスとして機能します。 このような式は、SQL ステートメントのどこにあるかにかかわらず、カラム識別子のかわりに使用できます。MySQLリファレンスマニュアル
先程の、JSON_EXTRACTと同様の結果を得ることができました。 JSON_EXTRACTに比べて、「->」演算子の方がSQL文の記述量が少なくなるので、可読性が上がると思います。

Goのtime.Time型をMySQLのDATETIME型にキャストしてソートする方法

timeも先ほど同様に記述すればソートはできますが、あくまでもJSON内の”文字列”での比較となってしまいます。

※正確には、公式リファレンス に以下のように記述されています。

文字列は、比較される2つの文字列のutf8mb4表現の最初のNバイトで字句的に順序付けされます(N は短い文字列の長さです)。 2つの文字列の最初のNバイトが同一の場合、短い文字列は長い文字列より小さいとみなされます。MySQLリファレンスマニュアル

正しく比較するにはMySQLのDATETIME型にキャストすることが安全かと思いますので、実装してみます。
 -> は値を抽出するだけの演算子ですが、 ->> は抽出された結果を引用符で囲まない演算子です。

日付でソートして出力することができました。

まとめ

MySQLにJSON型で永続化している場合は、指定した値の取得であっても一手間必要になります。 値の抽出やソートについて、公式のリファレンスには様々なケースが記載されているので、より良い書き方があれば取り入れていきたいと思います。

MySQL 8.0 リファレンスマニュアル
The following two tabs change content below.

totsuka

事業開発部 web application engineer
鉄道会社でバス・不動産部門を経験の後、エンジニア未経験ながらもアーティスへ入社。 事業開発部のエンジニアとして新規サービスの開発に携わっている。 エンジニア未経験での入社のため、つまずきながらも1,2ヶ月の研修を経て、現在では主にGoを使用したプロダクトコードのコーディングに従事している。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします