我有一个sqlite数据库,在其中一个字段中,我存储了完整的json对象。我必须提出一些json选择请求。如果看到我的json ALL键的值是一个数组。 我们需要提取一些数据,例如“ pod”字段为fb的所有注释。当sqlite json的值作为数组时,如何正确提取?
从数据表中选择json_extract(data,'$。“ json”');给我全部东西。那我做 选择json_extract(data,'$。“ json” [0]')但我不想手动进行。我想迭代。
请提供一些我可以研究和研究的资料。 我的JSON
{
"ALL": [{
"comments": "your site is awesome",
"pod": "passcode",
"originalDirectory": "case1"
},
{
"comments": "your channel is good",
"data": ["youTube"],
"pod": "library"
},
{
"comments": "you like everything",
"data": ["facebook"],
"pod": "fb"
},
{
"data": ["twitter"],
"pod": "tw",
"ALL": [{
"data": [{
"codeLevel": "3"
}],
"pod": "mo",
"pod2": "p"
}]
}
]
}
create table datatable ( path string , data json1 );
insert into datatable values("1" , json('<abovejson in a single line>'));
答案 0 :(得分:1)
在您的JSON表示注释的“简单”列表的情况下,您需要以下内容:
select key, value
from datatable, json_each( datatable.data, '$.ALL' )
where json_extract( value, '$.pod' ) = 'fb' ;
使用您的示例数据返回:
2|{"comments":"you like everything","data":["facebook"],"pod":"fb"}
使用json_each()
为输入JSON(datatable.data
)的每个元素返回一行,起始于路径$.ALL
(其中$
是顶级,并且ALL
是数组的名称:如果需要JSON对象的顶级,则可以省略路径)。就您而言,这将为每个评论条目返回一行。
该行的字段在SQLite文档的4.13. The json_each() and json_tree() table-valued functions中进行了记录:我们感兴趣的两个字段是key
(大致来说是“行号”)和value
(当前元素的JSON)。后者将包含名为comment
和pod
等的元素。
因为我们只对pod
等于fb
的元素感兴趣,所以我们添加了where
子句,使用json_extract()
来获得pod
(其中$.pod
相对于value
函数返回的json_each
。
如果您的JSON包含嵌套元素(起初我没有注意到),那么您需要使用json_tree()
函数而不是json_each()
。后者只会迭代指定节点的直接子节点,而json_tree()
将通过指定节点的 all 个子节点递归下降。
为了给我们一些数据,我在测试数据中增加了一个额外的元素:
create table datatable ( path string , data json1 );
insert into datatable values("1" , json('
{
"ALL": [{
"comments": "your site is awesome",
"pod": "passcode",
"originalDirectory": "case1"
},
{
"comments": "your channel is good",
"data": ["youTube"],
"pod": "library"
},
{
"comments": "you like everything",
"data": ["facebook"],
"pod": "fb"
},
{
"data": ["twitter"],
"pod": "tw",
"ALL": [{
"data": [{
"codeLevel": "3"
}],
"pod": "mo",
"pod2": "p"
},
{
"comments": "inserted by TripeHound",
"data": ["facebook"],
"pod": "fb"
}]
}
]
}
'));
如果我们只是简单地切换为使用json_each()
,那么我们会看到一个简单的查询(没有where
子句)将返回源JSON的 all 元素:
select key, value
from datatable, json_tree( datatable.data, '$.ALL' ) limit 10 ;
ALL|[{"comments":"your site is awesome","pod":"passcode","originalDirectory":"case1"},{"comments":"your channel is good","data":["youTube"],"pod":"library"},{"comments":"you like everything","data":["facebook"],"pod":"fb"},{"data":["twitter"],"pod":"tw","ALL":[{"data":[{"codeLevel":"3"}],"pod":"mo","pod2":"p"},{"comments":"inserted by TripeHound","data":["facebook"],"pod":"fb"}]}]
0|{"comments":"your site is awesome","pod":"passcode","originalDirectory":"case1"}
comments|your site is awesome
pod|passcode
originalDirectory|case1
1|{"comments":"your channel is good","data":["youTube"],"pod":"library"}
comments|your channel is good
data|["youTube"]
0|youTube
pod|library
由于JSON对象与简单值混合在一起,我们不能再简单地添加where json_extract( value, '$.pod' ) = 'fb'
,因为当value
不代表对象时,这会产生错误。解决此问题的最简单方法是查看type
/ json_each()
返回的json_tree()
值:如果该行表示一个JSON对象,则它们将是字符串object
(请参见上文)其他值的文档。)
将此内容添加到where
子句中(并依靠“短路评估”来防止在非对象行上调用json_extract()
),我们得到:
select key, value
from datatable, json_tree( datatable.data, '$.ALL' )
where type = 'object'
and json_extract( value, '$.pod' ) = 'fb' ;
返回:
2|{"comments":"you like everything","data":["facebook"],"pod":"fb"}
1|{"comments":"inserted by TripeHound","data":["facebook"],"pod":"fb"}
如果需要,我们可以使用json_extract()
拆分返回的对象:
.mode column
.headers on
.width 30 15 5
select json_extract( value, '$.comments' ) as Comments,
json_extract( value, '$.data' ) as Data,
json_extract( value, '$.pod' ) as POD
from datatable, json_tree( datatable.data, '$.ALL' )
where type = 'object'
and json_extract( value, '$.pod' ) = 'fb' ;
Comments Data POD
------------------------------ --------------- -----
you like everything ["facebook"] fb
inserted by TripeHound ["facebook"] fb
注意:如果您的结构包含其他对象,它们的格式不同,仅选择type = 'object'
可能还不够:您可能必须设计一个更细微的过滤过程。< / p>