How to unnest and GROUP BY elements of a JSON array?How to turn json array into postgres array?What does...
Tcolorbox :: sidebyside option gives poor result
find command cannot find my files which do exist
How to not forget my phone in the bathroom?
Why is autolanding ILS a thing, but not autotakeoffing ITS?
Prove that a cyclic group with only one generator can have at most 2 elements
Hollowed circle with crossed line and arrow
What prevents people from lying about where they live in order to reduce state income taxes?
Is it possible to detect 100% of SQLi with a simple regex?
Should you blow through the final approach course if the ATC forgot about you?
Why does RAM (any type) access time decrease so slowly?
Sing Baby Shark
How to write pow math?
Is 'bad luck' with former employees a red flag?
Why did Tywin never remarry?
Identical projects by students at two different colleges: still plagiarism?
Found a major flaw in paper from home university – to which I would like to return
Why does finding small effects in large studies indicate publication bias?
Which was the first story to feature space elevators?
Why is Bernie Sanders maximum accepted donation on actblue $5600?
Why are energy weapons seen as more acceptable in children's shows than guns that fire bullets?
Does human life have innate value over that of other animals?
Does limiting the number of sources help simplify the game for a new DM with new and experienced players?
Negotiating 1-year delay to my Assistant Professor Offer
Does a star need to be inside a galaxy?
How to unnest and GROUP BY elements of a JSON array?
How to turn json array into postgres array?What does [FROM x, y] mean in Postgres?How to remove known elements from a JSON[] array in PostgreSQL?How to remove known elements from a JSON[] array in PostgreSQL?PostgreSQL, finding elements by value in numeric JSON arraysUpdate Postgres Table with Array of JSONInsert Array of JSON into Postgres TableHow do I query a JSON array stored in a JSON object?Returning a json array slice in PostgreSQLAdding array element to JSON column in PostgreSQLHow do I conditionally select elements of an array?List JSON array in MySQL as rowsGet the max value from a slice of a JSON Array?
Given the band
table, with a json
column holding an array :
id | people
---+-------------
1 | ['George', 'John']
2 | ['Thomas', 'James']
3 | ['James', 'John']
How to list the number of bands each name is part of?
Desired output:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
postgresql group-by json array
add a comment |
Given the band
table, with a json
column holding an array :
id | people
---+-------------
1 | ['George', 'John']
2 | ['Thomas', 'James']
3 | ['James', 'John']
How to list the number of bands each name is part of?
Desired output:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
postgresql group-by json array
1
Ifpeople
is array (defined aspeople text[]
) you could use:select name, count(*) as c from ttt, unnest(people) as name group by name;
– ypercubeᵀᴹ
Jun 1 '18 at 18:58
1
If it's json or jsonb, you can usejson_array_elements_text()
instead ofunnest()
– ypercubeᵀᴹ
Jun 1 '18 at 19:06
Please remember to always disclose your version of Postgres. Ideally, add aCREATE TABLE
statement with exact data types and constraints to avoid ambiguities like withjson
vs.jsonb
.
– Erwin Brandstetter
Jun 4 '18 at 15:18
add a comment |
Given the band
table, with a json
column holding an array :
id | people
---+-------------
1 | ['George', 'John']
2 | ['Thomas', 'James']
3 | ['James', 'John']
How to list the number of bands each name is part of?
Desired output:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
postgresql group-by json array
Given the band
table, with a json
column holding an array :
id | people
---+-------------
1 | ['George', 'John']
2 | ['Thomas', 'James']
3 | ['James', 'John']
How to list the number of bands each name is part of?
Desired output:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
postgresql group-by json array
postgresql group-by json array
edited Jun 4 '18 at 15:23
Erwin Brandstetter
92.7k9176291
92.7k9176291
asked Jun 1 '18 at 18:51
BaxBax
1488
1488
1
Ifpeople
is array (defined aspeople text[]
) you could use:select name, count(*) as c from ttt, unnest(people) as name group by name;
– ypercubeᵀᴹ
Jun 1 '18 at 18:58
1
If it's json or jsonb, you can usejson_array_elements_text()
instead ofunnest()
– ypercubeᵀᴹ
Jun 1 '18 at 19:06
Please remember to always disclose your version of Postgres. Ideally, add aCREATE TABLE
statement with exact data types and constraints to avoid ambiguities like withjson
vs.jsonb
.
– Erwin Brandstetter
Jun 4 '18 at 15:18
add a comment |
1
Ifpeople
is array (defined aspeople text[]
) you could use:select name, count(*) as c from ttt, unnest(people) as name group by name;
– ypercubeᵀᴹ
Jun 1 '18 at 18:58
1
If it's json or jsonb, you can usejson_array_elements_text()
instead ofunnest()
– ypercubeᵀᴹ
Jun 1 '18 at 19:06
Please remember to always disclose your version of Postgres. Ideally, add aCREATE TABLE
statement with exact data types and constraints to avoid ambiguities like withjson
vs.jsonb
.
– Erwin Brandstetter
Jun 4 '18 at 15:18
1
1
If
people
is array (defined as people text[]
) you could use: select name, count(*) as c from ttt, unnest(people) as name group by name;
– ypercubeᵀᴹ
Jun 1 '18 at 18:58
If
people
is array (defined as people text[]
) you could use: select name, count(*) as c from ttt, unnest(people) as name group by name;
– ypercubeᵀᴹ
Jun 1 '18 at 18:58
1
1
If it's json or jsonb, you can use
json_array_elements_text()
instead of unnest()
– ypercubeᵀᴹ
Jun 1 '18 at 19:06
If it's json or jsonb, you can use
json_array_elements_text()
instead of unnest()
– ypercubeᵀᴹ
Jun 1 '18 at 19:06
Please remember to always disclose your version of Postgres. Ideally, add a
CREATE TABLE
statement with exact data types and constraints to avoid ambiguities like with json
vs. jsonb
.– Erwin Brandstetter
Jun 4 '18 at 15:18
Please remember to always disclose your version of Postgres. Ideally, add a
CREATE TABLE
statement with exact data types and constraints to avoid ambiguities like with json
vs. jsonb
.– Erwin Brandstetter
Jun 4 '18 at 15:18
add a comment |
3 Answers
3
active
oldest
votes
The data type of the column people
is json
, as is the result of json_array_elements(people)
. And there is no equality operator (=
) for the data type json
. So you also cannot run GROUP BY
on it. More:
- How to remove known elements from a JSON[] array in PostgreSQL?
jsonb
has an equality operator, so the "workaround" in your answer is to cast to jsonb
and use the equivalent jsonb_array_elements()
. The cast adds cost:
jsonb_array_elements(people::jsonb)
Since Postgres 9.4 we also have json_array_elements_text(json)
returning array elements as text
. Related:
- How to turn json array into postgres array?
So:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
GROUP BY p.name;
It seems more convenient to get names as text
instead of jsonb
objects (double-quoted in text representation) and your "desired output" indicates you want / need text
in the result to begin with.
GROUP BY
on text
data is also cheaper than on jsonb
, so this alternative "workaround" should be faster for two reasons. (Test with EXPLAIN (ANALYZE, TIMING OFF)
.)
For the record, there was nothing wrong with your original answer. The comma (,
) is just as "correct" as CROSS JOIN LATERAL
. Having been defined earlier in standard SQL does no make it inferior. See:
- What does [FROM x, y] mean in Postgres?
Neither is it more portable to other RDBMS, and since jsonb_array_elements()
or json_array_elements_text()
aren't portable to other RDBMS to begin with, that's also irrelevant. The short query does not get any clearer with CROSS JOIN LATERAL
IMO, but the last bit is just my personal opinion.
I used the more explicit table and column alias p(name)
and the table-qualified reference p.name
to defend against possible duplicate names. name
is such a common word, it might also pop up as column name in the underlying table band
, in which case it would silently resolve to band.name
. The simple form json_array_elements_text(people) name
only attaches a table alias, the column name is still value
, as returned from the function. But name
resolves to it's single column value
when used in the SELECT
list. It happens to work as expected. But a true column name name
(if band.name
should exist) would bind first. While that won't bite in the given example, it can be a a loaded foot gun in other cases.
Don't use the generic "name" as identifier to begin with. Maybe that was just for the simple test case.
If the column people
can hold anything but a plain JSON array, either query would trigger an exception. If you cannot guarantee data integrity, you might want to defend with json_typeof()
:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
WHERE json_typeof(b.people) = 'array'
GROUP BY 1; -- optional short syntax since you seem to prefer short syntax
Excludes violating rows from the query.
Related:
- When can we use an identifier number instead of its name in PostgreSQL?
add a comment |
Based on @ypercubeᵀᴹ comment I ended up with :
SELECT name, count(*) as c
FROM band
CROSS JOIN LATERAL jsonb_array_elements(people::jsonb) as name
GROUP BY name;
Just used jsonb_array_elements
instead of unnest
.
1
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
add a comment |
For someone in mysql
SELECT
JSON_EXTRACT(people, CONCAT('$[', idx, ']')) AS name, count(*) as count
FROM yourtable
JOIN subtable AS indexes
WHERE JSON_EXTRACT(people, CONCAT('$[', idx, '].id')) IS NOT NULL
group by name
.........
with subtable like: Colum: idx, row: 0,1,2,3,4,5,6,7,8,9......................
New contributor
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f208520%2fhow-to-unnest-and-group-by-elements-of-a-json-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The data type of the column people
is json
, as is the result of json_array_elements(people)
. And there is no equality operator (=
) for the data type json
. So you also cannot run GROUP BY
on it. More:
- How to remove known elements from a JSON[] array in PostgreSQL?
jsonb
has an equality operator, so the "workaround" in your answer is to cast to jsonb
and use the equivalent jsonb_array_elements()
. The cast adds cost:
jsonb_array_elements(people::jsonb)
Since Postgres 9.4 we also have json_array_elements_text(json)
returning array elements as text
. Related:
- How to turn json array into postgres array?
So:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
GROUP BY p.name;
It seems more convenient to get names as text
instead of jsonb
objects (double-quoted in text representation) and your "desired output" indicates you want / need text
in the result to begin with.
GROUP BY
on text
data is also cheaper than on jsonb
, so this alternative "workaround" should be faster for two reasons. (Test with EXPLAIN (ANALYZE, TIMING OFF)
.)
For the record, there was nothing wrong with your original answer. The comma (,
) is just as "correct" as CROSS JOIN LATERAL
. Having been defined earlier in standard SQL does no make it inferior. See:
- What does [FROM x, y] mean in Postgres?
Neither is it more portable to other RDBMS, and since jsonb_array_elements()
or json_array_elements_text()
aren't portable to other RDBMS to begin with, that's also irrelevant. The short query does not get any clearer with CROSS JOIN LATERAL
IMO, but the last bit is just my personal opinion.
I used the more explicit table and column alias p(name)
and the table-qualified reference p.name
to defend against possible duplicate names. name
is such a common word, it might also pop up as column name in the underlying table band
, in which case it would silently resolve to band.name
. The simple form json_array_elements_text(people) name
only attaches a table alias, the column name is still value
, as returned from the function. But name
resolves to it's single column value
when used in the SELECT
list. It happens to work as expected. But a true column name name
(if band.name
should exist) would bind first. While that won't bite in the given example, it can be a a loaded foot gun in other cases.
Don't use the generic "name" as identifier to begin with. Maybe that was just for the simple test case.
If the column people
can hold anything but a plain JSON array, either query would trigger an exception. If you cannot guarantee data integrity, you might want to defend with json_typeof()
:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
WHERE json_typeof(b.people) = 'array'
GROUP BY 1; -- optional short syntax since you seem to prefer short syntax
Excludes violating rows from the query.
Related:
- When can we use an identifier number instead of its name in PostgreSQL?
add a comment |
The data type of the column people
is json
, as is the result of json_array_elements(people)
. And there is no equality operator (=
) for the data type json
. So you also cannot run GROUP BY
on it. More:
- How to remove known elements from a JSON[] array in PostgreSQL?
jsonb
has an equality operator, so the "workaround" in your answer is to cast to jsonb
and use the equivalent jsonb_array_elements()
. The cast adds cost:
jsonb_array_elements(people::jsonb)
Since Postgres 9.4 we also have json_array_elements_text(json)
returning array elements as text
. Related:
- How to turn json array into postgres array?
So:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
GROUP BY p.name;
It seems more convenient to get names as text
instead of jsonb
objects (double-quoted in text representation) and your "desired output" indicates you want / need text
in the result to begin with.
GROUP BY
on text
data is also cheaper than on jsonb
, so this alternative "workaround" should be faster for two reasons. (Test with EXPLAIN (ANALYZE, TIMING OFF)
.)
For the record, there was nothing wrong with your original answer. The comma (,
) is just as "correct" as CROSS JOIN LATERAL
. Having been defined earlier in standard SQL does no make it inferior. See:
- What does [FROM x, y] mean in Postgres?
Neither is it more portable to other RDBMS, and since jsonb_array_elements()
or json_array_elements_text()
aren't portable to other RDBMS to begin with, that's also irrelevant. The short query does not get any clearer with CROSS JOIN LATERAL
IMO, but the last bit is just my personal opinion.
I used the more explicit table and column alias p(name)
and the table-qualified reference p.name
to defend against possible duplicate names. name
is such a common word, it might also pop up as column name in the underlying table band
, in which case it would silently resolve to band.name
. The simple form json_array_elements_text(people) name
only attaches a table alias, the column name is still value
, as returned from the function. But name
resolves to it's single column value
when used in the SELECT
list. It happens to work as expected. But a true column name name
(if band.name
should exist) would bind first. While that won't bite in the given example, it can be a a loaded foot gun in other cases.
Don't use the generic "name" as identifier to begin with. Maybe that was just for the simple test case.
If the column people
can hold anything but a plain JSON array, either query would trigger an exception. If you cannot guarantee data integrity, you might want to defend with json_typeof()
:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
WHERE json_typeof(b.people) = 'array'
GROUP BY 1; -- optional short syntax since you seem to prefer short syntax
Excludes violating rows from the query.
Related:
- When can we use an identifier number instead of its name in PostgreSQL?
add a comment |
The data type of the column people
is json
, as is the result of json_array_elements(people)
. And there is no equality operator (=
) for the data type json
. So you also cannot run GROUP BY
on it. More:
- How to remove known elements from a JSON[] array in PostgreSQL?
jsonb
has an equality operator, so the "workaround" in your answer is to cast to jsonb
and use the equivalent jsonb_array_elements()
. The cast adds cost:
jsonb_array_elements(people::jsonb)
Since Postgres 9.4 we also have json_array_elements_text(json)
returning array elements as text
. Related:
- How to turn json array into postgres array?
So:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
GROUP BY p.name;
It seems more convenient to get names as text
instead of jsonb
objects (double-quoted in text representation) and your "desired output" indicates you want / need text
in the result to begin with.
GROUP BY
on text
data is also cheaper than on jsonb
, so this alternative "workaround" should be faster for two reasons. (Test with EXPLAIN (ANALYZE, TIMING OFF)
.)
For the record, there was nothing wrong with your original answer. The comma (,
) is just as "correct" as CROSS JOIN LATERAL
. Having been defined earlier in standard SQL does no make it inferior. See:
- What does [FROM x, y] mean in Postgres?
Neither is it more portable to other RDBMS, and since jsonb_array_elements()
or json_array_elements_text()
aren't portable to other RDBMS to begin with, that's also irrelevant. The short query does not get any clearer with CROSS JOIN LATERAL
IMO, but the last bit is just my personal opinion.
I used the more explicit table and column alias p(name)
and the table-qualified reference p.name
to defend against possible duplicate names. name
is such a common word, it might also pop up as column name in the underlying table band
, in which case it would silently resolve to band.name
. The simple form json_array_elements_text(people) name
only attaches a table alias, the column name is still value
, as returned from the function. But name
resolves to it's single column value
when used in the SELECT
list. It happens to work as expected. But a true column name name
(if band.name
should exist) would bind first. While that won't bite in the given example, it can be a a loaded foot gun in other cases.
Don't use the generic "name" as identifier to begin with. Maybe that was just for the simple test case.
If the column people
can hold anything but a plain JSON array, either query would trigger an exception. If you cannot guarantee data integrity, you might want to defend with json_typeof()
:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
WHERE json_typeof(b.people) = 'array'
GROUP BY 1; -- optional short syntax since you seem to prefer short syntax
Excludes violating rows from the query.
Related:
- When can we use an identifier number instead of its name in PostgreSQL?
The data type of the column people
is json
, as is the result of json_array_elements(people)
. And there is no equality operator (=
) for the data type json
. So you also cannot run GROUP BY
on it. More:
- How to remove known elements from a JSON[] array in PostgreSQL?
jsonb
has an equality operator, so the "workaround" in your answer is to cast to jsonb
and use the equivalent jsonb_array_elements()
. The cast adds cost:
jsonb_array_elements(people::jsonb)
Since Postgres 9.4 we also have json_array_elements_text(json)
returning array elements as text
. Related:
- How to turn json array into postgres array?
So:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
GROUP BY p.name;
It seems more convenient to get names as text
instead of jsonb
objects (double-quoted in text representation) and your "desired output" indicates you want / need text
in the result to begin with.
GROUP BY
on text
data is also cheaper than on jsonb
, so this alternative "workaround" should be faster for two reasons. (Test with EXPLAIN (ANALYZE, TIMING OFF)
.)
For the record, there was nothing wrong with your original answer. The comma (,
) is just as "correct" as CROSS JOIN LATERAL
. Having been defined earlier in standard SQL does no make it inferior. See:
- What does [FROM x, y] mean in Postgres?
Neither is it more portable to other RDBMS, and since jsonb_array_elements()
or json_array_elements_text()
aren't portable to other RDBMS to begin with, that's also irrelevant. The short query does not get any clearer with CROSS JOIN LATERAL
IMO, but the last bit is just my personal opinion.
I used the more explicit table and column alias p(name)
and the table-qualified reference p.name
to defend against possible duplicate names. name
is such a common word, it might also pop up as column name in the underlying table band
, in which case it would silently resolve to band.name
. The simple form json_array_elements_text(people) name
only attaches a table alias, the column name is still value
, as returned from the function. But name
resolves to it's single column value
when used in the SELECT
list. It happens to work as expected. But a true column name name
(if band.name
should exist) would bind first. While that won't bite in the given example, it can be a a loaded foot gun in other cases.
Don't use the generic "name" as identifier to begin with. Maybe that was just for the simple test case.
If the column people
can hold anything but a plain JSON array, either query would trigger an exception. If you cannot guarantee data integrity, you might want to defend with json_typeof()
:
SELECT p.name, count(*) AS c
FROM band b, json_array_elements_text(b.people) p(name)
WHERE json_typeof(b.people) = 'array'
GROUP BY 1; -- optional short syntax since you seem to prefer short syntax
Excludes violating rows from the query.
Related:
- When can we use an identifier number instead of its name in PostgreSQL?
edited Jun 4 '18 at 15:47
answered Jun 4 '18 at 15:06
Erwin BrandstetterErwin Brandstetter
92.7k9176291
92.7k9176291
add a comment |
add a comment |
Based on @ypercubeᵀᴹ comment I ended up with :
SELECT name, count(*) as c
FROM band
CROSS JOIN LATERAL jsonb_array_elements(people::jsonb) as name
GROUP BY name;
Just used jsonb_array_elements
instead of unnest
.
1
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
add a comment |
Based on @ypercubeᵀᴹ comment I ended up with :
SELECT name, count(*) as c
FROM band
CROSS JOIN LATERAL jsonb_array_elements(people::jsonb) as name
GROUP BY name;
Just used jsonb_array_elements
instead of unnest
.
1
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
add a comment |
Based on @ypercubeᵀᴹ comment I ended up with :
SELECT name, count(*) as c
FROM band
CROSS JOIN LATERAL jsonb_array_elements(people::jsonb) as name
GROUP BY name;
Just used jsonb_array_elements
instead of unnest
.
Based on @ypercubeᵀᴹ comment I ended up with :
SELECT name, count(*) as c
FROM band
CROSS JOIN LATERAL jsonb_array_elements(people::jsonb) as name
GROUP BY name;
Just used jsonb_array_elements
instead of unnest
.
edited Jun 1 '18 at 19:31
answered Jun 1 '18 at 19:06
BaxBax
1488
1488
1
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
add a comment |
1
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
1
1
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
@See my update to your syntax for the newer way to do this.
– Evan Carroll
Jun 1 '18 at 19:18
add a comment |
For someone in mysql
SELECT
JSON_EXTRACT(people, CONCAT('$[', idx, ']')) AS name, count(*) as count
FROM yourtable
JOIN subtable AS indexes
WHERE JSON_EXTRACT(people, CONCAT('$[', idx, '].id')) IS NOT NULL
group by name
.........
with subtable like: Colum: idx, row: 0,1,2,3,4,5,6,7,8,9......................
New contributor
add a comment |
For someone in mysql
SELECT
JSON_EXTRACT(people, CONCAT('$[', idx, ']')) AS name, count(*) as count
FROM yourtable
JOIN subtable AS indexes
WHERE JSON_EXTRACT(people, CONCAT('$[', idx, '].id')) IS NOT NULL
group by name
.........
with subtable like: Colum: idx, row: 0,1,2,3,4,5,6,7,8,9......................
New contributor
add a comment |
For someone in mysql
SELECT
JSON_EXTRACT(people, CONCAT('$[', idx, ']')) AS name, count(*) as count
FROM yourtable
JOIN subtable AS indexes
WHERE JSON_EXTRACT(people, CONCAT('$[', idx, '].id')) IS NOT NULL
group by name
.........
with subtable like: Colum: idx, row: 0,1,2,3,4,5,6,7,8,9......................
New contributor
For someone in mysql
SELECT
JSON_EXTRACT(people, CONCAT('$[', idx, ']')) AS name, count(*) as count
FROM yourtable
JOIN subtable AS indexes
WHERE JSON_EXTRACT(people, CONCAT('$[', idx, '].id')) IS NOT NULL
group by name
.........
with subtable like: Colum: idx, row: 0,1,2,3,4,5,6,7,8,9......................
New contributor
New contributor
answered 6 mins ago
Long AivyLong Aivy
1
1
New contributor
New contributor
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f208520%2fhow-to-unnest-and-group-by-elements-of-a-json-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
If
people
is array (defined aspeople text[]
) you could use:select name, count(*) as c from ttt, unnest(people) as name group by name;
– ypercubeᵀᴹ
Jun 1 '18 at 18:58
1
If it's json or jsonb, you can use
json_array_elements_text()
instead ofunnest()
– ypercubeᵀᴹ
Jun 1 '18 at 19:06
Please remember to always disclose your version of Postgres. Ideally, add a
CREATE TABLE
statement with exact data types and constraints to avoid ambiguities like withjson
vs.jsonb
.– Erwin Brandstetter
Jun 4 '18 at 15:18