简单列表
你的 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 对象的顶级,则路径可以省略是必须的)。在您的情况下,这将为每个评论条目返回一行。
此行的字段记录在4.13 中。SQLite 文档中的 json_each() 和 json_tree() 表值函数:我们感兴趣的两个是key
(非常粗略地,“行号”)和value
(当前元素的 JSON)。后者将包含名为comment
andpod
等的元素。
因为我们只对pod
等于的元素感兴趣fb
,所以我们添加一个where
子句,使用json_extract()
to get at pod
(where$.pod
是相对于函数value
返回的json_each
)。
嵌套列表
如果您的 JSON 包含嵌套元素(我一开始没有注意到),那么您需要使用该json_tree()
函数而不是json_each()
. 而后者只会遍历指定节点的直接子节点,json_tree()
将递归地遍历指定节点的所有子节点。
为了给我们一些数据,我用一个额外的元素扩充了你的测试数据:
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"
}]
}
]
}
'));
如果我们只是简单地切换到 using json_each()
,那么我们会看到一个简单的查询(没有where
子句)将返回源 JSON 的所有元素:
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 对象,这些将是字符串(有关其他值,请参见上面的文档)。json_each()
json_tree()
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
注意:如果您的结构包含其他不同格式的对象,那么简单地选择 for 可能是不够的type = 'object'
:您可能需要设计一个更微妙的过滤过程。