web-dev-qa-db-ja.com

MySQLのJSON配列に、特定の日付を保持するキーを持つオブジェクトが含まれているかどうかを確認します

jSON配列内に特定の日付を含む行があるかどうかを確認しようとしています

私のデータが次のようになっているとしましょう:

テーブルアプリケーション:

id | application_id | data
# Rows
1 | 1 | [{"data" : ["some", "data#1"], "date": "2016-04-21"}, {"data" : ["other", "data#1"], "date" : "2016-04-22"}]
2 | 2 | [{"data" : ["some", "data#2"], "date": "2016-04-21"}, {"data" : ["other", "data#2"], "date" : "2016-04-26"}]
3 | 1 | [{"data" : ["some", "data#3"], "date": "2016-04-22"}, {"data" : ["other", "data#3"], "date" : "2016-04-26"}]
4 | 3 | [{"data" : ["some", "data#4"], "date": "2016-04-26"}]

データに日付'2016-04-26'が含まれているすべてのアプリケーションを見つけるにはどうすればよいですか?

だから基本的にこれを行うことができます:

select id, json_extract(`data`, "$[*].date") from applications

どちらが戻ります:

1 | ["2016-04-21", "2016-04-22"]
2 | ["2016-04-21", "2016-04-26"]
3 | ["2016-04-22", "2016-04-26"]
4 | ["2016-04-26"]

ただし、WHERE句でjson_extractを使用しようとすると、json_extractのパス引数で配列のキーを明示的に指定した場合にのみ、次のように使用できます。

select * from applications where json_extract(`data`, "$[0].date") = "2016-04-26"

これにより、ID 4の行が正しく返されます。

しかし、パスでワイルドカードを使用しようとすると、機能しなくなります。

select * from applications where json_extract(`data`, "$[*].date") = "2016-04-26"

これにより、行2、3、4が返されます。

他の多くのオプション/バリエーションを試しましたが、クエリを正しく構成する方法を見つけることができません。

MySQL JSONの現在の実装でも、このようなことは可能ですか?

18
Klemen

Morgan Tuckerが提供する1つの解決策-@morgoは、次のようにjson_containsを使用することです。

select * from applications where json_contains(`data`, '{"date" : "2016-04-26"}')

現時点では答えはOKですが、パフォーマンスの問題があり、少しハックしているように感じると思います(次のクエリを参照)。

日付範囲(2016-04-24から2016-04-26まで)でクエリを実行する必要がある場合は、次のように時間帯の各日に個別のjson_containsを追加する必要があります。

select * from applications where json_contains(`data`, '{"date" : "2016-04-26"}') or json_contains(`data`, '{"date" : "2016-04-25"}') or json_contains(`data`, '{"date" : "2016-04-24"}')

そして、dateキーを他の場所にネストすると、無効なデータが返されます。

だからあなたが別の解決策を持っているなら、私は知りたいのですが

15
Klemen