SQLite
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> SQLite

SQLite JSON_TREE ()

Trong SQLite, json_tree() là một hàm có giá trị bảng, đi giá trị JSON được cung cấp làm đối số đầu tiên của nó và trả về một bảng bao gồm một hàng cho mỗi phần tử mảng hoặc thành viên đối tượng.

Chúng tôi cung cấp giá trị JSON làm đối số khi chúng tôi gọi hàm.

Chúng ta có thể tùy chọn chuyển đối số thứ hai, đối số này chỉ định một đường dẫn để bắt đầu. Khi chúng tôi thực hiện việc này, json_tree() coi đường dẫn đó là phần tử cấp cao nhất.

json_tree() hàm đệ quy đi qua cấu trúc con JSON bắt đầu với phần tử cấp cao nhất. Để chỉ đi bộ phần tử con trực tiếp của mảng hoặc đối tượng cấp cao nhất hoặc chỉ bản thân phần tử cấp cao nhất nếu phần tử cấp cao nhất là một giá trị nguyên thủy, hãy sử dụng json_each() chức năng thay thế.

Cú pháp

Chúng ta có thể sử dụng json_tree() hoạt động theo những cách sau:

json_tree(X)
json_tree(X,P)

Trong đó X đại diện cho JSON và P là một đối số tùy chọn đại diện cho đường dẫn được coi là cấp cao nhất.

Ví dụ

Dưới đây là một ví dụ để chứng minh cách hoạt động:

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

Kết quả:

+------+--------------------------+---------+------+----+--------+---------+------+
| 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   | $    |
+------+--------------------------+---------+------+----+--------+---------+------+

Chúng ta có thể thấy rằng mỗi thành viên đối tượng có hàng riêng với một số thông tin hữu ích, chẳng hạn như kiểu của nó (giá trị văn bản SQL), đường dẫn, v.v.

Về id , theo tài liệu SQLite, đây là số quản lý nội bộ, việc tính toán số này có thể thay đổi trong các bản phát hành trong tương lai. Đảm bảo duy nhất là id cột sẽ khác nhau cho mọi hàng.

Mảng

Trong ví dụ này, giá trị JSON là một mảng:

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

Kết quả:

+------+------------+---------+------+----+--------+---------+------+
| 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]    | $    |
+------+------------+---------+------+----+--------+---------+------+

Chỉ định một đường dẫn

Chúng ta có thể sử dụng đối số thứ hai để chỉ định một đường dẫn được coi là cấp cao nhất.

Ví dụ:

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

Kết quả:

+-----+---------+---------+------+----+--------+---------+------+
| 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  |
+-----+---------+---------+------+----+--------+---------+------+

Tài liệu lớn hơn

Trong ví dụ này, chúng tôi sẽ sử dụng tài liệu JSON lớn hơn. Đầu tiên, hãy gọi json_tree() mà không chỉ định đường dẫn:

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 ]
        }
        ]'
    );

Kết quả:

+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
|  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 |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+

Trong trường hợp này, giá trị JSON của chúng ta là một mảng chứa ba đối tượng. Mỗi đối tượng được liệt kê trong kết quả và từng thành viên của các đối tượng đó được liệt kê, cùng với các giá trị tương ứng của chúng, v.v.

Bây giờ, hãy gọi json_tree() một lần nữa, nhưng lần này chúng tôi sẽ chỉ định một đường dẫn:

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]'
    );

Kết quả:

+--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+
|  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 |
+--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+

Trong trường hợp này, tôi đã chọn phần tử mảng thứ hai bằng cách chỉ định [1] (mảng bằng 0 dựa trên SQLite).

Kết quả là cây chỉ được giới hạn ở phần tử mảng thứ hai.

Hãy đi sâu hơn:

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'
    );

Kết quả:

+--------+------------+---------+------+----+--------+----------------+-------------+
|  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 |
+--------+------------+---------+------+----+--------+----------------+-------------+

Càng vào sâu, số hàng bị trả về càng ít. Đó là bởi vì chúng tôi chỉ nhận được một cây bắt đầu từ đường dẫn cụ thể mà chúng tôi đã chỉ định.

Lọc truy vấn

Chúng tôi có thể sửa đổi truy vấn của mình để lọc kết quả dựa trên một tiêu chí nhất định. Ví dụ:

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%';

Kết quả:

+-----------+--------------------------------------------------------------+
|  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                                                         |
+-----------+--------------------------------------------------------------+

Chúng tôi chỉ có thể trả lại hàng cuối cùng bằng cách thực hiện điều này:

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';

Kết quả:

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

Trả lại các nút lá

Chúng ta có thể giới hạn kết quả chỉ với các nút lá nếu chúng ta muốn. Với "nút lá", ý tôi là chỉ những khóa không có phần tử con nào khác.

Có một vài cách để làm điều này.

Một tùy chọn là lọc ra tất cả các đối tượng và mảng:

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');

Kết quả:

+------+-------+---------+-------+----+--------+----------------+-------------+
| 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 |
+------+-------+---------+-------+----+--------+----------------+-------------+

Một cách khác để làm điều đó là kiểm tra atom cột cho giá trị null. Cụ thể, chúng tôi chỉ trả về các hàng mà cột này doesn't chứa giá trị rỗng:

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;

Kết quả:

+------+-------+---------+-------+----+--------+----------------+-------------+
| 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 cột là giá trị SQL tương ứng với các phần tử nguyên thủy - các phần tử không phải là mảng và đối tượng JSON. Cột này luôn null cho một mảng hoặc đối tượng JSON. Giá trị value cột giống với atom cột cho các phần tử JSON nguyên thủy nhưng nhận giá trị JSON văn bản cho các mảng và đối tượng.

Một ví dụ về cơ sở dữ liệu

Giả sử chúng ta có bảng sau:

SELECT * FROM scores;

Kết quả:

+---------+---------------------------------------------------------+
| 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]}] |
+---------+---------------------------------------------------------+

Bảng này được gọi là scores có hai cột. Cột đầu tiên chứa tên của giáo viên và cột thứ hai chứa tài liệu JSON. Tài liệu JSON chứa các sinh viên và điểm số của họ.

Dưới đây là ví dụ về cách chạy truy vấn sử dụng json_tree() so với bảng này:

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

Kết quả:

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

Tại đây, chúng tôi đã trả lại tất cả điểm cho Liz và chúng tôi cũng trả lại giáo viên của cô ấy.

Truy vấn sau trả về điểm thứ hai của cô ấy:

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

Kết quả:

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

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ListView không hiển thị các hình ảnh chính xác trong có thể vẽ theo tên của chúng trong sqlite

  2. Cách đặt từng mục được truy xuất từ ​​cơ sở dữ liệu SQLite thành Chế độ xem văn bản của riêng mục đó

  3. Hoạt động và Dịch vụ Nền Truy cập vào Cơ sở dữ liệu SQLite

  4. Android SQLite LIKE ký tự đại diện thoát

  5. Chỉ mục dựa trên biểu thức SQLite