One thing that would be nice is if SQL provided first class support for sub records.
So instead of "SELECT name, (SELECT GROUP_CONCAT(CONCAT_WS(',', post_id, post) SEPARATOR ';') FROM posts p WHERE p.user_id = u.user_id) AS 'posts' FROM users u WHERE u.user_id = 1",
you could do "SELECT name, (SELECT post_id, post FROM posts p WHERE p.user_id = u.user_id) AS 'posts' FROM users u WHERE u.user_id = 1".
and the query result would be { name : 'Todd', posts : [ { post_id : 1, post : 'My Comment' } ] }.
Obviously this is a simple example and could have been rewritten as a query on the posts table, inner joined on the user table, and duplicating the user's name in the result. But it becomes much nicer to have as queries get more complex.
A query that supports sub records would gives you flexibility to structure data like a JSON object and simplify the server end of REST apis.
What if you only want the id and markup of each post?
Postgres 9.4 gave us json_build_object:
SELECT
u.name,
array_agg(
json_build_object(
'id', p.id,
'markup', p.markup
)
) posts
FROM users u, posts p
WHERE p.user_id = u.user_id
GROUP BY u.user_id;
If you're just trying to get JSON out (for a simple query to REST api, or in a node.js environment), have you considered converting the record/recordset to json in the subquery?
The json functions in 9.3+ are pretty handy for that sort of thing. Andrew (core developer who wrote most of that functionality) and I decided to keep the api pretty lightweight, as its easy to also add your own functions to suit your needs.
JSON functions do look pretty helpful and go a long way, even if not first class. As you can tell from syntax I'm stuck in the MySQL/MariaDB world, so not up with everything in PostgreSQL. This and the features in the slideshare are an eye opener to me. Thanks!
So instead of "SELECT name, (SELECT GROUP_CONCAT(CONCAT_WS(',', post_id, post) SEPARATOR ';') FROM posts p WHERE p.user_id = u.user_id) AS 'posts' FROM users u WHERE u.user_id = 1",
you could do "SELECT name, (SELECT post_id, post FROM posts p WHERE p.user_id = u.user_id) AS 'posts' FROM users u WHERE u.user_id = 1".
and the query result would be { name : 'Todd', posts : [ { post_id : 1, post : 'My Comment' } ] }.
Obviously this is a simple example and could have been rewritten as a query on the posts table, inner joined on the user table, and duplicating the user's name in the result. But it becomes much nicer to have as queries get more complex.
A query that supports sub records would gives you flexibility to structure data like a JSON object and simplify the server end of REST apis.