-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgetting-started.sql
188 lines (152 loc) · 3.92 KB
/
getting-started.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
---- db: -h localhost -p 7890 -U postgres postgres
-- Create JSONB
-- RFC 7159 https://tools.ietf.org/html/rfc7159
select '1'::jsonb;
select 'false'::jsonb;
select '"value"'::jsonb;
select '{"attribute": "value"}'::jsonb;
----
select
$JSON$
{
"attribute": "value",
"nested": {"nested_attribute": "nested value"}
}
$JSON$::jsonb;
----
----
-- Pretty print
\a
select jsonb_pretty('{
"attribute": "value",
"nested": {"nested_attribute": "nested value"}
}'::jsonb);
-- Other constructors (json_build_object and json_build_array) we will review later
----
-- Access operators: -> ->> #> #>>
-- - get key or index
-- # get path
-- > return json value
-- >> return text
----
-- ->
\set record '{"key": "value", "nested": {"key": "nested value"}}'
\echo 'Operator -> Get JSON object field by key or index'
select jsonb_pretty((:'record')::jsonb) record;
select
'record->''key''' as access,
(:'record')::jsonb->'key' as value,
pg_typeof((:'record')::jsonb->'key');
select
'record->''nested''' as access,
(:'record')::jsonb->'nested' as value,
pg_typeof((:'record')::jsonb->'nested');
----
-- ->>
\set record '{"key": "value", "nested": {"key": "nested value"}}'
\echo 'Operator ->> Get JSON object field or array element as text'
select jsonb_pretty((:'record')::jsonb) record;
select
'record->>''key''' as access,
(:'record')::jsonb->>'key' as value,
pg_typeof((:'record')::jsonb->>'key');
select
'record->>''nested''' as access,
(:'record')::jsonb->>'nested' as value,
pg_typeof((:'record')::jsonb->>'nested');
----
-- #>
\set record '{"key": "value", "nested": {"key": "nested value"}}'
\echo 'Operator #> Get JSON object at specified path'
select jsonb_pretty((:'record')::jsonb) record;
select
'record#>''{nested,key}''' as access,
(:'record')::jsonb#>'{nested,key}' as value,
pg_typeof((:'record')::jsonb#>'{nested,key}');
----
-- #>>
\set record '{"key": "value", "nested": {"key": "nested value"}}'
\echo 'Operator #>> Get JSON object at specified path as text'
select jsonb_pretty((:'record')::jsonb) record;
select
'record#>>''{nested,key}''' as access,
(:'record')::jsonb#>>'{nested,key}' as value,
pg_typeof((:'record')::jsonb#>>'{nested,key}');
----
-- Read
-- equivalent to #> operator
select jsonb_extract_path(
'{"attr": "value", "nested": {"foo": "bar"}}'::jsonb, 'nested', 'foo'
);
-- equivalent to #>> operator
select jsonb_extract_path_text(
'{"attr": "value", "nested": {"foo": "bar"}}'::jsonb, 'nested', 'foo'
);
----
-- Create table for Github Commits
----
-- Now load last 300 commits ifo of PostgreSQL from github
-- $ ./github.sh
-- link https://api.github.com/repos/postgres/postgres/commits
----
-- NOTE: if github ban your IP, you can use commits_bk table
-- select count(*) from commits_bk;
-----
create table commits (
id text primary key,
doc jsonb
);
----
\a
select jsonb_pretty(doc)
from commits_bk
limit 1;
----
select
doc#>>'{author,login}' login,
count(*) commits
from commits_bk
group by doc#>>'{author,login}'
order by count(*) desc ;
-----
-- coerce
select
(doc#>>'{commit,author,date}')::date,
doc#>>'{commit,author,name}',
doc#>>'{commit,author,email}',
count(*)
from commits_bk
group by
(doc#>>'{commit,author,date}')::date,
doc#>>'{commit,author,name}',
doc#>>'{commit,author,email}'
order by count(*) desc
limit 50;
-----
-- Extra task: analyze data - keys usage
select count(*) from commits;
with recursive r AS (
select attr.key as path, attr.value as val
from commits p,
jsonb_each(doc) attr
UNION
(
WITH prev AS (
select * from r
), obj AS (
select path || '.' || attr.key as path, attr.value as val
from prev, jsonb_each(val) attr
where jsonb_typeof(val) = 'object'
), arr AS (
select path as path, attr as val
from prev, jsonb_array_elements(val) attr
where jsonb_typeof(val) = 'array'
)
select * from obj union select * from arr
)
)
select path, count(*)
from r
group by path
order by count(*) desc;
-----