sql >> データベース >  >> RDS >> SQLite

SQLite JSON_TREE()

    SQLiteでは、json_tree() は、最初の引数として提供されたJSON値をウォークし、配列要素またはオブジェクトメンバーごとに1行で構成されるテーブルを返すテーブル値関数です。

    関数を呼び出すときに引数としてJSON値を提供します。

    オプションで、開始するパスを指定する2番目の引数を渡すことができます。これを行うとき、json_tree() そのパスを最上位の要素として扱います。

    json_tree() 関数は、最上位の要素から始まるJSONサブ構造を再帰的にウォークスルーします。トップレベルの配列またはオブジェクトの直接の子のみ、またはトップレベルの要素がプリミティブ値の場合はトップレベルの要素自体のみをウォークするには、json_each()を使用します。 代わりに機能します。

    構文

    json_tree()を使用できます 次のように機能します:

    json_tree(X)
    json_tree(X,P)

    Xの場所 JSONを表し、P は、トップレベルとして扱うパスを表すオプションの引数です。

    これがどのように機能するかを示す例です。

    SELECT * FROM json_tree('{ "name" : "Woof", "age" : 10 }');

    結果:

    +------+--------------------------+---------+------+----+--------+---------+------+
    | key  |          value           |  type   | atom | id | parent | fullkey | path |
    +------+--------------------------+---------+------+----+--------+---------+------+
    | null | {"name":"Woof","age":10} | object  | null | 0  | null   | $       | $    |
    | name | Woof                     | text    | Woof | 2  | 0      | $.name  | $    |
    | age  | 10                       | integer | 10   | 4  | 0      | $.age   | $    |
    +------+--------------------------+---------+------+----+--------+---------+------+

    各オブジェクトメンバーには、タイプ(SQLテキスト値)やパスなどの有用な情報を含む独自の行があることがわかります。

    idについて 列、SQLiteのドキュメントによると、これは内部のハウスキーピング番号であり、その計算は将来のリリースで変更される可能性があります。唯一の保証は、id 列は行ごとに異なります。

    配列

    この例では、JSON値は配列です:

    SELECT * FROM json_tree('[ 10, 30, 45 ]');

    結果:

    +------+------------+---------+------+----+--------+---------+------+
    | key  |   value    |  type   | atom | id | parent | fullkey | path |
    +------+------------+---------+------+----+--------+---------+------+
    | null | [10,30,45] | array   | null | 0  | null   | $       | $    |
    | 0    | 10         | integer | 10   | 1  | 0      | $[0]    | $    |
    | 1    | 30         | integer | 30   | 2  | 0      | $[1]    | $    |
    | 2    | 45         | integer | 45   | 3  | 0      | $[2]    | $    |
    +------+------------+---------+------+----+--------+---------+------+

    パスを指定

    2番目の引数を使用して、トップレベルとして扱うパスを指定できます。

    例:

    SELECT * FROM json_tree('{ "a" : 1, "b" : [ 4, 7, 8 ] }', '$.b');

    結果:

    +-----+---------+---------+------+----+--------+---------+------+
    | key |  value  |  type   | atom | id | parent | fullkey | path |
    +-----+---------+---------+------+----+--------+---------+------+
    | b   | [4,7,8] | array   | null | 4  | null   | $.b     | $    |
    | 0   | 4       | integer | 4    | 5  | 4      | $.b[0]  | $.b  |
    | 1   | 7       | integer | 7    | 6  | 4      | $.b[1]  | $.b  |
    | 2   | 8       | integer | 8    | 7  | 4      | $.b[2]  | $.b  |
    +-----+---------+---------+------+----+--------+---------+------+

    より大きなドキュメント

    この例では、より大きなJSONドキュメントを使用します。まず、json_tree()を呼び出しましょう パスを指定せずに:

    SELECT * FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]'
        );

    結果:

    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    |  key   |                            value                             |  type   | atom  |  id  | parent |    fullkey     |    path     |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | null   | [{"user":"Spike","age":30,"scores":[9,7,3]},{"user":"Faye"," | array   | null  | 0    | null   | $              | $           |
    | null   | age":25,"scores":[90,87,93]},{"user":"Jet","age":40,"scores  | null    | null  | null | null   | null           | null        |
    | null   | ":[50,38,67]}]                                               | null    | null  | null | null   | null           | null        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 0      | {"user":"Spike","age":30,"scores":[9,7,3]}                   | object  | null  | 1    | 0      | $[0]           | $           |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | user   | Spike                                                        | text    | Spike | 3    | 1      | $[0].user      | $[0]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | age    | 30                                                           | integer | 30    | 5    | 1      | $[0].age       | $[0]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | scores | [9,7,3]                                                      | array   | null  | 7    | 1      | $[0].scores    | $[0]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 0      | 9                                                            | integer | 9     | 8    | 7      | $[0].scores[0] | $[0].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 1      | 7                                                            | integer | 7     | 9    | 7      | $[0].scores[1] | $[0].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 2      | 3                                                            | integer | 3     | 10   | 7      | $[0].scores[2] | $[0].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 1      | {"user":"Faye","age":25,"scores":[90,87,93]}                 | object  | null  | 11   | 0      | $[1]           | $           |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | user   | Faye                                                         | text    | Faye  | 13   | 11     | $[1].user      | $[1]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | age    | 25                                                           | integer | 25    | 15   | 11     | $[1].age       | $[1]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | scores | [90,87,93]                                                   | array   | null  | 17   | 11     | $[1].scores    | $[1]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 0      | 90                                                           | integer | 90    | 18   | 17     | $[1].scores[0] | $[1].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 1      | 87                                                           | integer | 87    | 19   | 17     | $[1].scores[1] | $[1].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 2      | 93                                                           | integer | 93    | 20   | 17     | $[1].scores[2] | $[1].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 2      | {"user":"Jet","age":40,"scores":[50,38,67]}                  | object  | null  | 21   | 0      | $[2]           | $           |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | user   | Jet                                                          | text    | Jet   | 23   | 21     | $[2].user      | $[2]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | age    | 40                                                           | integer | 40    | 25   | 21     | $[2].age       | $[2]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | scores | [50,38,67]                                                   | array   | null  | 27   | 21     | $[2].scores    | $[2]        |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 0      | 50                                                           | integer | 50    | 28   | 27     | $[2].scores[0] | $[2].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 1      | 38                                                           | integer | 38    | 29   | 27     | $[2].scores[1] | $[2].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
    | 2      | 67                                                           | integer | 67    | 30   | 27     | $[2].scores[2] | $[2].scores |
    +--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+

    この場合、JSON値は3つのオブジェクトを含む配列です。結果には各オブジェクトが一覧表示され、それらの各オブジェクトのメンバーがそれぞれの値とともに一覧表示されます。

    それでは、json_tree()を呼び出しましょう。 繰り返しますが、今回はパスを指定します:

    SELECT * FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]',
            '$[1]'
        );

    結果:

    +--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+
    |  key   |                    value                     |  type   | atom | id | parent |    fullkey     |    path     |
    +--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+
    | null   | {"user":"Faye","age":25,"scores":[90,87,93]} | object  | null | 11 | null   | $[0]           | $           |
    | user   | Faye                                         | text    | Faye | 13 | 11     | $[0].user      | $[0]        |
    | age    | 25                                           | integer | 25   | 15 | 11     | $[0].age       | $[0]        |
    | scores | [90,87,93]                                   | array   | null | 17 | 11     | $[0].scores    | $[0]        |
    | 0      | 90                                           | integer | 90   | 18 | 17     | $[0].scores[0] | $[0].scores |
    | 1      | 87                                           | integer | 87   | 19 | 17     | $[0].scores[1] | $[0].scores |
    | 2      | 93                                           | integer | 93   | 20 | 17     | $[0].scores[2] | $[0].scores |
    +--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+

    この場合、[1]を指定して2番目の配列要素を選択しました (配列はSQLiteに基づいてゼロです。)

    その結果、ツリーは2番目の配列要素のみに制限されます。

    もっと深く見ていきましょう:

    SELECT * FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]',
            '$[1].scores'
        );

    結果:

    +--------+------------+---------+------+----+--------+----------------+-------------+
    |  key   |   value    |  type   | atom | id | parent |    fullkey     |    path     |
    +--------+------------+---------+------+----+--------+----------------+-------------+
    | scores | [90,87,93] | array   | null | 17 | null   | $[0].scores    | $[0]        |
    | 0      | 90         | integer | 90   | 18 | 17     | $[0].scores[0] | $[0].scores |
    | 1      | 87         | integer | 87   | 19 | 17     | $[0].scores[1] | $[0].scores |
    | 2      | 93         | integer | 93   | 20 | 17     | $[0].scores[2] | $[0].scores |
    +--------+------------+---------+------+----+--------+----------------+-------------+

    深く進むほど、返される行は少なくなります。これは、指定した特定のパスで始まるツリーのみを取得しているためです。

    クエリのフィルタリング

    クエリを変更して、特定の基準に基づいて結果をフィルタリングできます。例:

    SELECT 
        fullkey, 
        value 
    FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]'
        )
    WHERE json_tree.value LIKE '%Faye%';

    結果:

    +-----------+--------------------------------------------------------------+
    |  fullkey  |                            value                             |
    +-----------+--------------------------------------------------------------+
    | $         | [{"user":"Spike","age":30,"scores":[9,7,3]},{"user":"Faye"," |
    | null      | age":25,"scores":[90,87,93]},{"user":"Jet","age":40,"scores  |
    | null      | ":[50,38,67]}]                                               |
    +-----------+--------------------------------------------------------------+
    | $[1]      | {"user":"Faye","age":25,"scores":[90,87,93]}                 |
    +-----------+--------------------------------------------------------------+
    | $[1].user | Faye                                                         |
    +-----------+--------------------------------------------------------------+

    これを行うことで、最後の行だけを返すことができます:

    SELECT *
    FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]'
        )
    WHERE json_tree.value = 'Faye';

    結果:

    +------+-------+------+------+----+--------+-----------+------+
    | key  | value | type | atom | id | parent |  fullkey  | path |
    +------+-------+------+------+----+--------+-----------+------+
    | user | Faye  | text | Faye | 13 | 11     | $[1].user | $[1] |
    +------+-------+------+------+----+--------+-----------+------+

    リターンリーフノード

    必要に応じて、結果をリーフノードのみに制限できます。 「リーフノード」とは、それ以上の子要素を持たないキーのみを意味します。

    これを行うにはいくつかの方法があります。

    1つのオプションは、すべてのオブジェクトと配列を除外することです。

    SELECT * 
    FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]'
        )
    WHERE json_tree.type NOT IN ('object','array');

    結果:

    +------+-------+---------+-------+----+--------+----------------+-------------+
    | key  | value |  type   | atom  | id | parent |    fullkey     |    path     |
    +------+-------+---------+-------+----+--------+----------------+-------------+
    | user | Spike | text    | Spike | 3  | 1      | $[0].user      | $[0]        |
    | age  | 30    | integer | 30    | 5  | 1      | $[0].age       | $[0]        |
    | 0    | 9     | integer | 9     | 8  | 7      | $[0].scores[0] | $[0].scores |
    | 1    | 7     | integer | 7     | 9  | 7      | $[0].scores[1] | $[0].scores |
    | 2    | 3     | integer | 3     | 10 | 7      | $[0].scores[2] | $[0].scores |
    | user | Faye  | text    | Faye  | 13 | 11     | $[1].user      | $[1]        |
    | age  | 25    | integer | 25    | 15 | 11     | $[1].age       | $[1]        |
    | 0    | 90    | integer | 90    | 18 | 17     | $[1].scores[0] | $[1].scores |
    | 1    | 87    | integer | 87    | 19 | 17     | $[1].scores[1] | $[1].scores |
    | 2    | 93    | integer | 93    | 20 | 17     | $[1].scores[2] | $[1].scores |
    | user | Jet   | text    | Jet   | 23 | 21     | $[2].user      | $[2]        |
    | age  | 40    | integer | 40    | 25 | 21     | $[2].age       | $[2]        |
    | 0    | 50    | integer | 50    | 28 | 27     | $[2].scores[0] | $[2].scores |
    | 1    | 38    | integer | 38    | 29 | 27     | $[2].scores[1] | $[2].scores |
    | 2    | 67    | integer | 67    | 30 | 27     | $[2].scores[2] | $[2].scores |
    +------+-------+---------+-------+----+--------+----------------+-------------+

    これを行う別の方法は、atomをチェックすることです。 null値の列。具体的には、この列がdoesn't行のみを返します。 null値が含まれています:

    SELECT * 
    FROM json_tree('[
            { 
            "user" : "Spike",
            "age" : 30,
            "scores" : [ 9, 7, 3 ]
            },
            { 
            "user" : "Faye",
            "age" : 25,
            "scores" : [ 90, 87, 93 ]
            },
            { 
            "user" : "Jet",
            "age" : 40,
            "scores" : [ 50, 38, 67 ]
            }
            ]'
        )
    WHERE atom IS NOT NULL;

    結果:

    +------+-------+---------+-------+----+--------+----------------+-------------+
    | key  | value |  type   | atom  | id | parent |    fullkey     |    path     |
    +------+-------+---------+-------+----+--------+----------------+-------------+
    | user | Spike | text    | Spike | 3  | 1      | $[0].user      | $[0]        |
    | age  | 30    | integer | 30    | 5  | 1      | $[0].age       | $[0]        |
    | 0    | 9     | integer | 9     | 8  | 7      | $[0].scores[0] | $[0].scores |
    | 1    | 7     | integer | 7     | 9  | 7      | $[0].scores[1] | $[0].scores |
    | 2    | 3     | integer | 3     | 10 | 7      | $[0].scores[2] | $[0].scores |
    | user | Faye  | text    | Faye  | 13 | 11     | $[1].user      | $[1]        |
    | age  | 25    | integer | 25    | 15 | 11     | $[1].age       | $[1]        |
    | 0    | 90    | integer | 90    | 18 | 17     | $[1].scores[0] | $[1].scores |
    | 1    | 87    | integer | 87    | 19 | 17     | $[1].scores[1] | $[1].scores |
    | 2    | 93    | integer | 93    | 20 | 17     | $[1].scores[2] | $[1].scores |
    | user | Jet   | text    | Jet   | 23 | 21     | $[2].user      | $[2]        |
    | age  | 40    | integer | 40    | 25 | 21     | $[2].age       | $[2]        |
    | 0    | 50    | integer | 50    | 28 | 27     | $[2].scores[0] | $[2].scores |
    | 1    | 38    | integer | 38    | 29 | 27     | $[2].scores[1] | $[2].scores |
    | 2    | 67    | integer | 67    | 30 | 27     | $[2].scores[2] | $[2].scores |
    +------+-------+---------+-------+----+--------+----------------+-------------+

    atom columnは、プリミティブ要素(JSON配列およびオブジェクト以外の要素)に対応するSQL値です。この列は常にnull JSON配列またはオブジェクトの場合。 value 列はatomと同じです プリミティブJSON要素の列ですが、配列とオブジェクトのテキストJSON値を取ります。

    データベースの例

    次の表があるとします。

    SELECT * FROM scores;

    結果:

    +---------+---------------------------------------------------------+
    | teacher |                        students                         |
    +---------+---------------------------------------------------------+
    | Zohan   | [{"Amy":[10,8,9]},{"Josh":[3,2,4]},{"Igor":[7,6,5]}]    |
    | Stacy   | [{"Pete":[5,3,1]},{"Liz":[5,8,7]},{"Jet":[9,5,7]}]      |
    | Aisha   | [{"Zolton":[4,6,7]},{"Bree":[7,7,4]},{"Rohit":[9,8,8]}] |
    +---------+---------------------------------------------------------+

    このテーブルはscoresと呼ばれます 2つの列があります。最初の列には教師の名前が含まれ、2番目の列にはJSONドキュメントが含まれます。 JSONドキュメントには、学生とそのスコアが含まれています。

    json_tree()を使用するクエリを実行する例を次に示します。 このテーブルに対して:

    SELECT
        teacher,
        key AS student,
        value
    FROM 
        scores, 
        json_tree(students, '$[1].Liz')
    WHERE json_tree.key = 'Liz';

    結果:

    +---------+---------+---------+
    | teacher | student |  value  |
    +---------+---------+---------+
    | Stacy   | Liz     | [5,8,7] |
    +---------+---------+---------+

    ここでは、リズのすべてのスコアを返し、彼女の先生も返しました。

    次のクエリは彼女の2番目のスコアを返します:

    SELECT
        teacher,
        key AS student,
        value AS score
    FROM 
        scores, 
        json_tree(students, '$[1].Liz')
    WHERE json_tree.key = 1;

    結果:

    +---------+---------+-------+
    | teacher | student | score |
    +---------+---------+-------+
    | Stacy   | 1       | 8     |
    +---------+---------+-------+

    1. SQLのピアソン相関係数式

    2. MySQLにビュークエリにINDEXを使用させるにはどうすればよいですか?

    3. Oracleで特定のテーブルがいつ作成されたかを確認するにはどうすればよいですか?

    4. 接続エラー時にODP.NET接続プールをクリアするにはどうすればよいですか?