【问题标题】:How to concatenate values into string in MySQL如何在 MySQL 中将值连接成字符串
【发布时间】:2014-09-11 01:19:17
【问题描述】:

我有这个 SQL 表:

user_skills 
==========================      
user_id | skill_id | value
   1    |    4     |   1
   1    |    5     |   1
   1    |    6     |   1
   1    |    7     |   1
   1    |    8     |   1
   2    |    4     |   1
   2    |    6     |   1
   4    |    4     |   1
   4    |    5     |   1
   5    |    8     |   1

然后,我有一个 SQL 查询,它返回有关用户的信息。

$mysqli->query("SELECT  u.*,
                        COUNT(a.user_id) AS jobs,
                        r.*
                FROM users u
                LEFT JOIN articles a
                    ON u.id = a.user_id
                LEFT JOIN rating r
                    ON r.user_id = u.id
                LEFT JOIN regions r1
                    ON r1.id = u.city
                WHERE   u.active = 1 AND
                        u.server_id IN (" . $server_id . ")
                GROUP BY (CASE WHEN a.user_id IS NULL THEN u.id ELSE a.user_id END)
                ORDER BY    u.points DESC,
                            jobs_done DESC,
                            u.id DESC
                LIMIT " . (($page - 1) * $limit) . ", " . ($page * $limit));

现在,我需要为每个用户选择他们的技能,或者更好,skill_ids。理想情况下是用逗号分隔的字符串,因为我们只讨论了 5 个 Skill_id (4-8)。

我试过了:

$mysqli->query("SELECT  u.*,
                        COUNT(a.user_id) AS jobs,
                        r.*,
                        CONCAT_WS(',', us.skill_id) AS skill_ids
                FROM users u
                LEFT JOIN articles a
                    ON u.id = a.user_id
                LEFT JOIN rating r
                    ON r.user_id = u.id
                LEFT JOIN regions r1
                    ON r1.id = u.city
                LEFT JOIN user_skills us
                    ON us.user_id = u.id AND skill_id IN (4, 5, 6, 7, 8)
                WHERE   u.active = 1 AND
                        u.server_id IN (" . $server_id . ")
                GROUP BY (CASE WHEN a.user_id IS NULL THEN u.id ELSE a.user_id END)
                ORDER BY    u.points DESC,
                            jobs_done DESC,
                            u.id DESC
                LIMIT " . (($page - 1) * $limit) . ", " . ($page * $limit));

但它只返回数据库中的第一个skill_id,没有连接。

当我尝试使用CONCAT_WS(',', us.skill_id) AS skill_ids 时,结果是逗号和第一个skill_id (, 4)。

数据库中的数据正常,SUM(us.skill_id)id=4 的用户返回 30

有什么想法吗?

【问题讨论】:

  • 也许错误出在其他地方 - 或者您正在寻找 GROUP_CONCAT()
  • @Strawberry:感谢您的快速回答(应该是回答,而不是评论)。它工作正常。我认为它应该是圣。像“group_”或“_group”,但在dev.mysql.com/doc/refman/5.0/en/string-functions.html 中没有这个名字。 +1

标签: mysql sql concatenation


【解决方案1】:

你有两个主要问题......

A) 您想要的函数是GROUP_CONCAT(),它为组生成一个 CSV 值。此查询为您提供每个用户的技能列表:

select user_id, group_concat(skill_id) as skill_ids
from user_skills
group by user_id

B) 一个更大的问题是您对GROUP BY 的错误使用:要使其按预期工作,您必须列出不是聚合函数的每个 列,使用位置数字或表达式.

假设 users 表有 6 列,而 rating 有 4:

SELECT
    u.*,
    COUNT(a.user_id) AS jobs,
    r.*,
    GROUP_CONCAT(us.skill_id) AS skill_ids
FROM ...
...
GROUP BY 1,2,3,4,5,6, 8,9,10,11,12 -- note 7 is missing

或者您可以在 GROUP BY 中列出列表达式:

GROUP BY u.id, u.name, ..., r.id, r.foo, ...

即使您省略一个非聚合列,它也不会按预期工作。这种特殊的行为仅限于 mysql - 如果您遗漏了一个,其他所有数据库都会引发语法异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2021-10-05
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 2016-12-12
    相关资源
    最近更新 更多