SQLite
 sql >> база данни >  >> RDS >> SQLite

SQLite JSON_TREE()

В SQLite, json_tree() е функция с таблична стойност, която обхожда стойността на JSON, предоставена като първи аргумент, и връща таблица, състояща се от един ред за всеки елемент на масива или член на обекта.

Ние предоставяме стойността на JSON като аргумент, когато извикваме функцията.

Можем по избор да предадем втори аргумент, който определя път, от който да започнем. Когато направим това, 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 }'); 

Резултат:

+------+---------------------------+---------+-- ----+----+-------+-------+-----+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+------+------------------------------+--------+--- ---+----+-------+-------+-----+| нула | {"name":"Wow","age":10} | обект | нула | 0 | нула | $ | $ || име | Уф | текст | Уф | 2 | 0 | $.name | $ || възраст | 10 | цяло число | 10 | 4 | 0 | $.възраст | $ |+------+------------------------------+--------+--- ---+----+-------+-------+------+

Можем да видим, че всеки член на обекта има свой собствен ред с полезна информация, като например неговия тип (SQL текстова стойност), път и т.н.

Относно id колона, според документацията на SQLite това е вътрешен номер за домакинство, чието изчисляване може да се промени в бъдещи издания. Единствената гаранция е, че id колоната ще бъде различна за всеки ред.

Масив

В този пример стойността на JSON е масив:

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

Резултат:

+------+------------+--------+------+----+---- ----+---------+------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+------+------------+--------+------+----+----- ---+--------+------+| нула | [10,30,45] | масив | нула | 0 | нула | $ | $ || 0 | 10 | цяло число | 10 | 1 | 0 | $[0] | $ || 1 | 30 | цяло число | 30 | 2 | 0 | $[1] | $ || 2 | 45 | цяло число | 45 | 3 | 0 | $[2] | $ |+------+------------+--------+------+----+----- ---+--------+------+

Посочете път

Можем да използваме втори аргумент, за да посочим път, който да третираме като най-високо ниво.

Пример:

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

Резултат:

+-----+--------+--------+------+----+-------- +---------+------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+-----+--------+--------+------+----+--------+ ---------+------+| б | [4,7,8] | масив | нула | 4 | нула | $.b | $ || 0 | 4 | цяло число | 4 | 5 | 4 | $.b[0] | $.b || 1 | 7 | цяло число | 7 | 6 | 4 | $.b[1] | $.b || 2 | 8 | цяло число | 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 ]
        }
        ]'
    ); 

Резултат:

+--------+---------------------------------------------- -------------------------+--------+-------+------ +-------+----------------+------------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+--------+---------------------------------------------- ------------------------+--------+-------+-----+ --------+----------------+------------+| нула | [{"user":"Spike","age":30,"cores":[9,7,3]},{"user":"Faye"," | масив | null | 0 | null | $ | $ || null | age":25,"cores":[90,87,93]},{"user":"Jet","age":40,"cores | null | null | null | null | null | нула || нула | ":[50,38,67]}] | нула | нула | нула | нула | нула | нула |+--------+---------------------------------------------- ------------------------+--------+-------+-----+ --------+----------------+------------+| 0 | {"user":"Spike","age":30,"cores":[9,7,3]} | обект | нула | 1 | 0 | $[0] | $ |+--------+---------------------------------------------- ------------------------+--------+-------+-----+ --------+----------------+------------+| потребител | Спайк | текст | Спайк | 3 | 1 | $[0].потребител | $[0] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| възраст | 30 | цяло число | 30 | 5 | 1 | $[0].възраст | $[0] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| резултати | [9,7,3] | масив | нула | 7 | 1 | $[0].резултати | $[0] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| 0 | 9 | цяло число | 9 | 8 | 7 | $[0].резултати[0] | $[0].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 1 | 7 | цяло число | 7 | 9 | 7 | $[0].резултати[1] | $[0].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 2 | 3 | цяло число | 3 | 10 | 7 | $[0].резултати[2] | $[0].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 1 | {"user":"Faye","age":25,"cores":[90,87,93]} | обект | нула | 11 | 0 | $[1] | $ |+--------+---------------------------------------------- ------------------------+--------+-------+-----+ --------+----------------+------------+| потребител | Фей | текст | Фей | 13 | 11 | $[1].потребител | $[1] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| възраст | 25 | цяло число | 25 | 15 | 11 | $[1].възраст | $[1] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| резултати | [90,87,93] | масив | нула | 17 | 11 | $[1].резултати | $[1] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| 0 | 90 | цяло число | 90 | 18 | 17 | $[1].резултати[0] | $[1].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 1 | 87 | цяло число | 87 | 19 | 17 | $[1].резултати[1] | $[1].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 2 | 93 | цяло число | 93 | 20 | 17 | $[1].резултати[2] | $[1].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 2 | {"user":"Jet","age":40,"cores":[50,38,67]} | обект | нула | 21 | 0 | $[2] | $ |+--------+---------------------------------------------- ------------------------+--------+-------+-----+ --------+----------------+------------+| потребител | Реактивен | текст | Реактивен | 23 | 21 | $[2].потребител | $[2] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| възраст | 40 | цяло число | 40 | 25 | 21 | $[2].възраст | $[2] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| резултати | [50,38,67] | масив | нула | 27 | 21 | $[2].резултати | $[2] |+--------+---------------------------------- ---------------------------+--------+-------+---- --+-------+----------------+------------+| 0 | 50 | цяло число | 50 | 28 | 27 | $[2].резултати[0] | $[2].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 1 | 38 | цяло число | 38 | 29 | 27 | $[2].резултати[1] | $[2].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+| 2 | 67 | цяло число | 67 | 30 | 27 | $[2].резултати[2] | $[2].резултати |+--------+-------------------------------- ----------------------------+--------+-------+-- ----+-------+----------------+------------+

В този случай нашата 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 ]
        }
        ]',
        '$[1]'
    ); 

Резултат:

+--------+---------------------------------------------- ---------+--------+------+----+--------+-------- -------+------------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+--------+---------------------------------------------- --------+--------+------+----+--------+--------- ------+------------+| нула | {"user":"Faye","age":25,"cores":[90,87,93]} | обект | нула | 11 | нула | $[0] | $ || потребител | Фей | текст | Фей | 13 | 11 | $[0].потребител | $[0] || възраст | 25 | цяло число | 25 | 15 | 11 | $[0].възраст | $[0] || резултати | [90,87,93] | масив | нула | 17 | 11 | $[0].резултати | $[0] || 0 | 90 | цяло число | 90 | 18 | 17 | $[0].резултати[0] | $[0].резултати || 1 | 87 | цяло число | 87 | 19 | 17 | $[0].резултати[1] | $[0].резултати || 2 | 93 | цяло число | 93 | 20 | 17 | $[0].резултати[2] | $[0].резултати |+--------+-------------------------------- -------------+--------+------+----+-------+----- -----------+------------+

В този случай избрах втория елемент от масива, като посочих [1] (масивите са нулеви, базирани в SQLite).

Резултатът е, че дървото е ограничено само до втория елемент на масива.

Да отидем по-дълбоко:

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

Резултат:

+--------+------------+--------+------+----+-- ------+----------------+------------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+--------+------------+--------+------+----+--- -----+----------------+------------+| резултати | [90,87,93] | масив | нула | 17 | нула | $[0].резултати | $[0] || 0 | 90 | цяло число | 90 | 18 | 17 | $[0].резултати[0] | $[0].резултати || 1 | 87 | цяло число | 87 | 19 | 17 | $[0].резултати[1] | $[0].резултати || 2 | 93 | цяло число | 93 | 20 | 17 | $[0].резултати[2] | $[0].резултати |+--------+------------+--------+------+--- -+-------+----------------+------------+

Колкото по-дълбоко отиваме, толкова по-малко редове се връщат. Това е така, защото получаваме само дърво, което започва от конкретния път, който посочихме.

Филтриране на заявката

Можем да модифицираме нашата заявка, за да филтрираме резултатите въз основа на даден критерий. Например:

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

Резултат:

+-----------+--------------------------------- ----------------------------+| пълен ключ | стойност |+-----------+----------------------------------- ---------------------------+| $ | [{"user":"Spike","age":30,"cores":[9,7,3]},{"user":"Faye"," || null | age":25,"резултати ":[90,87,93]},{"user":"Jet","age":40,"резултати || null | ":[50,38,67]}] |+----- ------+--------------------------------------------------- -------------------+| $[1] | {"user":"Faye","age":25,"cores":[90,87,93]} |+-----------+--------- -------------------------------------------------- ---+| $[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.value = 'Faye'; 

Резултат:

+------+-------+------+------+----+--------+--- ---------+------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+------+-------+------+-----+----+--------+---- -------+------+| потребител | Фей | текст | Фей | 13 | 11 | $[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'); 

Резултат:

+------+-------+--------+-------+----+-------- +----------------+------------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+------+-------+--------+-------+----+-------+ ----------------+------------+| потребител | Спайк | текст | Спайк | 3 | 1 | $[0].потребител | $[0] || възраст | 30 | цяло число | 30 | 5 | 1 | $[0].възраст | $[0] || 0 | 9 | цяло число | 9 | 8 | 7 | $[0].резултати[0] | $[0].резултати || 1 | 7 | цяло число | 7 | 9 | 7 | $[0].резултати[1] | $[0].резултати || 2 | 3 | цяло число | 3 | 10 | 7 | $[0].резултати[2] | $[0].резултати || потребител | Фей | текст | Фей | 13 | 11 | $[1].потребител | $[1] || възраст | 25 | цяло число | 25 | 15 | 11 | $[1].възраст | $[1] || 0 | 90 | цяло число | 90 | 18 | 17 | $[1].резултати[0] | $[1].резултати || 1 | 87 | цяло число | 87 | 19 | 17 | $[1].резултати[1] | $[1].резултати || 2 | 93 | цяло число | 93 | 20 | 17 | $[1].резултати[2] | $[1].резултати || потребител | Реактивен | текст | Реактивен | 23 | 21 | $[2].потребител | $[2] || възраст | 40 | цяло число | 40 | 25 | 21 | $[2].възраст | $[2] || 0 | 50 | цяло число | 50 | 28 | 27 | $[2].резултати[0] | $[2].резултати || 1 | 38 | цяло число | 38 | 29 | 27 | $[2].резултати[1] | $[2].резултати || 2 | 67 | цяло число | 67 | 30 | 27 | $[2].резултати[2] | $[2].резултати |+------+-------+---------+-------+----+---- ----+----------------+------------+

Друг начин да го направите е да проверите atom колона за нулеви стойности. По-конкретно, бихме връщали само редове, където тази колона doesn't съдържат нулева стойност:

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; 

Резултат:

+------+-------+--------+-------+----+-------- +----------------+------------+| ключ | стойност | тип | атом | ID | родител | пълен ключ | път |+------+-------+--------+-------+----+-------+ ----------------+------------+| потребител | Спайк | текст | Спайк | 3 | 1 | $[0].потребител | $[0] || възраст | 30 | цяло число | 30 | 5 | 1 | $[0].възраст | $[0] || 0 | 9 | цяло число | 9 | 8 | 7 | $[0].резултати[0] | $[0].резултати || 1 | 7 | цяло число | 7 | 9 | 7 | $[0].резултати[1] | $[0].резултати || 2 | 3 | цяло число | 3 | 10 | 7 | $[0].резултати[2] | $[0].резултати || потребител | Фей | текст | Фей | 13 | 11 | $[1].потребител | $[1] || възраст | 25 | цяло число | 25 | 15 | 11 | $[1].възраст | $[1] || 0 | 90 | цяло число | 90 | 18 | 17 | $[1].резултати[0] | $[1].резултати || 1 | 87 | цяло число | 87 | 19 | 17 | $[1].резултати[1] | $[1].резултати || 2 | 93 | цяло число | 93 | 20 | 17 | $[1].резултати[2] | $[1].резултати || потребител | Реактивен | текст | Реактивен | 23 | 21 | $[2].потребител | $[2] || възраст | 40 | цяло число | 40 | 25 | 21 | $[2].възраст | $[2] || 0 | 50 | цяло число | 50 | 28 | 27 | $[2].резултати[0] | $[2].резултати || 1 | 38 | цяло число | 38 | 29 | 27 | $[2].резултати[1] | $[2].резултати || 2 | 67 | цяло число | 67 | 30 | 27 | $[2].резултати[2] | $[2].резултати |+------+-------+---------+-------+----+---- ----+----------------+------------+

atom колоната е SQL стойността, съответстваща на примитивни елементи – елементи, различни от JSON масиви и обекти. Тази колона винаги е null за JSON масив или обект. value колоната е същата като atom колона за примитивни JSON елементи, но приема текстовата JSON стойност за масиви и обекти.

Пример за база данни

Да предположим, че имаме следната таблица:

SELECT * FROM scores; 

Резултат:

+--------+------------------------------------ ---------------------+| учител | студенти |+--------+------------------------------------- --------------------+| Зохан | [{"Ейми":[10,8,9]},{"Джош":[3,2,4]},{"Игор":[7,6,5]}] || Стейси | [{"Pete":[5,3,1]},{"Liz":[5,8,7]},{"Jet":[9,5,7]}] || Айша | [{"Zolton":[4,6,7]},{"Bree":[7,7,4]},{"Rohit":[9,8,8]}] |+----- ----+----------------------------------------------------- ------------+

Тази таблица се нарича scores има две колони. Първата колона съдържа името на учителя, а втората колона съдържа JSON документ. Документът JSON съдържа учениците и техните резултати.

Ето пример за изпълнение на заявка, която използва json_tree() срещу тази таблица:

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

Резултат:

<пред>+--------+--------+--------+| учител | студент | стойност |+--------+--------+--------+| Стейси | Лиз | [5,8,7] |+--------+--------+--------+

Тук върнахме всички резултати за Лиз и върнахме нейния учител.

Следната заявка връща втория й резултат:

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

Резултат:

+--------+--------+-------+| учител | студент | резултат |+--------+--------+-------+| Стейси | 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. SQLite ляво присъединяване

  2. Запазване на данни в метода onDestroy на дейността

  3. Android – Курсор onMapReady (Маркери)

  4. Тестване на модули за база данни на Android SQLite

  5. Android стая - Как да изчистите sqlite_sequence за цялата таблица