SQL连接和组项目作为数组

Gra*_*les 7 mysql sql join

我有以下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
Run Code Online (Sandbox Code Playgroud)

这可以正常工作,除了它为文章所拥有的每个标签创建一行,其中包含限制

例如

[
 "0" => ["id" => "1", "title" => "test", "tags" => "tag1"],
 "1" => ["id" => "1", "title" => "test", "tags" => "tag2"],
 "2" => ["id" => "2", "title" => "test2", "tags" => "tag1"],
]
Run Code Online (Sandbox Code Playgroud)

(只有2篇文章,但有3行)

有没有办法让它用一系列标签返回每篇文章?

就像是:

[
 "0" => ["id" => "1", "title" => "test", "tags" => ["tag1", "tag2"]],
 "1" => ["id" => "2", "title" => "test2", "tags" => ["tag1"]],
]
Run Code Online (Sandbox Code Playgroud)

Dav*_*795 6

SELECT articles.id, articles.title, GROUP_CONCAT(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
GROUP BY articles.id
Run Code Online (Sandbox Code Playgroud)

你不能在 mysql 中返回一个数组,但是你可以得到这个连接后的字符串并在 PHP 端将它拆分成一个数组。您可以选择一个用于 'glue' 的字符GROUP_CONCAT(name SEPARATOR '#'),作为一个不应出现在任何名称中的字符,因此可以安全地拆分到数组中。

  • @RaphaëlAlthaus SQL 没有数组的概念。 (2认同)

kri*_* KM 6

默认情况下,您无法返回数组.但是你可以装饰/连接你的列以产生一个像字符串一样的数组.如果这是一个好主意?取决于你的情况.另请注意MySQL对group_concat有一些限制(只返回1024*字符)

无论如何只是为了测试目的你可以试试这个:

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
Run Code Online (Sandbox Code Playgroud)

这将为每行提供一个数组,如果你想要一行中的所有内容将它们全部放在group_concat下.

注意:如果您的结果大于1024个字符,则必须使用

SET group_concat_max_len = 1000000; >> size of your string length
Run Code Online (Sandbox Code Playgroud)

PS:尚未测试上面的代码.测试它:)