Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL join and group items as an array

Tags:

sql

join

mysql

I have the following SQL

SELECT articles.id, articles.title, tags.name AS tags
FROM articles
LEFT JOIN article_tag_association ON articles.id = article_tag_association.article_id
LEFT JOIN tags ON tags.id = article_tag_association.tag_id

This works OK except it creates a row for each tag an article has, which messes with the limit

e.g.

[
 "0" => ["id" => "1", "title" => "test", "tags" => "tag1"],
 "1" => ["id" => "1", "title" => "test", "tags" => "tag2"],
 "2" => ["id" => "2", "title" => "test2", "tags" => "tag1"],
]

(only 2 articles but three rows)

is there a way to make it return each article with an array of tags?

something like:

[
 "0" => ["id" => "1", "title" => "test", "tags" => ["tag1", "tag2"]],
 "1" => ["id" => "2", "title" => "test2", "tags" => ["tag1"]],
]
like image 579
Graham Fowles Avatar asked Nov 10 '14 15:11

Graham Fowles


People also ask

Can you JOIN on an array in SQL?

This is the function to use if you want to concatenate all the values in an array field into one string value. You can specify an optional argument as a separator, and it can be any string. If you do not specify a separator, there will be nothing aded between the values.

Can we use GROUP BY and JOIN together?

SQL Inner Join permits us to use Group by clause along with aggregate functions to group the result set by one or more columns. Group by works conventionally with Inner Join on the final result returned after joining two or more tables.

What are the 4 types of SQL JOIN operations?

There are four main types of JOINs in SQL: INNER JOIN, OUTER JOIN, CROSS JOIN, and SELF JOIN.

Can you GROUP BY coalesce?

Because the COALESCE is an expression, you can use it in any clause that accepts an expression such as SELECT , WHERE , GROUP BY , and HAVING .


1 Answers

by default you cannot return an array. but you can decorate/concatenate your columns to produce an array like string. if its a good idea? depends on your situation. Also please be aware MySQL has some limitations for group_concat (will only return 1024*chars)

anyway just for test purpose you can try this:

SELECT 
    concat(
    '[',
    concat('ID => "', articles.id,'"'),
    concat('Title => "', articles.title,'"'),
    concat('Tags => [', GROUP_CONCAT(concat('"',tags.name, '"')), ']'),
    ']'
    ) as Array_String
FROM
    articles
        LEFT JOIN
    article_tag_association ON articles.id = article_tag_association.article_id
        LEFT JOIN
    tags ON tags.id = article_tag_association.tag_id
GROUP BY articles.id

this will give you each row as an array, if you want everything in one line put them all under a group_concat.

note: if your result is larger than 1024 char you have to use

SET group_concat_max_len = 1000000; >> size of your string length

PS: haven't tested above code. test it :)

like image 141
Krish Avatar answered Sep 17 '22 17:09

Krish