方案
我想获取用户拥有的注册语言以及所有用户详细信息,我当前的问题是,当我GROUP_CONCAT
目标列时,值会重复。有人可以解释为什么值被重复。
我的表格
// users
+------+-------------+------------+----------------+--------------+
| id | firstname | lastname | email | created_at |
+------+-------------+------------+----------------+--------------+
| 10 | John | Doe | john@doe.com | 2014-10-21 |
+------+-------------+------------+----------------+--------------+
// teachers
+------+-----------+------------------+-------------------+
| id | user_id | years_teaching | months_teaching |
+------+-----------+------------------+-------------------+
| 35 | 10 | 3 | 6 |
+------+-----------+------------------+-------------------+
// teacher_languages
+------+--------------+---------------+----------+---------+
| id | teacher_id | language_id | status | views |
+------+--------------+---------------+----------+---------+
| 52 | 35 | 5 | 1 | 80 |
+------+--------------+---------------+----------+---------+
| 53 | 35 | 7 | 1 | 40 |
+------+--------------+---------------+----------+---------+
// translators
+------+-----------+------------------------+---------------------+
| id | user_id | certified_translator | accept_travelling |
+------+-----------+------------------------+---------------------+
| 23 | 10 | 0 | 1 |
+------+-----------+------------------------+---------------------+
// translator_languages
+------+-----------------+---------------+----------+---------+
| id | translator_id | language_id | status | views |
+------+-----------------+---------------+----------+---------+
| 52 | 23 | 5 | 1 | 27 |
+------+-----------------+---------------+----------+---------+
| 53 | 23 | 7 | 1 | 82 |
+------+-----------------+---------------+----------+---------+
// languages
+------+-----------------+------------+
| id | language_text | language |
+------+-----------------+------------+
| 5 | English | EN |
+------+-----------------+------------+
| 7 | French | FR |
+------+-----------------+------------+
当前查询
这是产生重复值的查询
SELECT
u.*,
// teacher languages
GROUP_CONCAT(l.language_text) AS teacher_languages,
GROUP_CONCAT(tl.status) AS teacher_languages_status,
GROUP_CONCAT(tl.views) AS teacher_language_views
// translator languages
GROUP_CONCAT(trl_txt.language_text) AS translator_languages,
GROUP_CONCAT(trl.status) AS translator_languages_status,
GROUP_CONCAT(trl.views) AS translator_language_views
FROM
users u
LEFT JOIN
teachers t ON t.user_id = u.id
LEFT JOIN
teacher_languages tl ON tl.teacher_id = t.id
LEFT JOIN
languages l ON l.id = tl.language_id
LEFT JOIN
translators tr ON tr.user_id = u.id
LEFT JOIN
translator_languages trl ON trl.teacher_id = t.id
LEFT JOIN
languages trl_txt ON trl_txt.id = trl.language_id
GROUP BY
u.id
ORDER BY
u.created_at
结果
[0] =>
[id] => 10
[firstname] => 'John'
[lastname] => 'Doe'
[email] => 'john@doe.com'
[created_at] => '2014-10-21'
[teacher_languages] => 'English, English, French, French'
[teacher_language_status] => '1,1,1,1'
[teacher_language_views] => '80,40,80,40'
[translator_languages] => 'English, French, English, French'
[translator_language_status] => '1,1,1,1'
[translator_language_views] => '27,82,27,82'
答案 0 :(得分:1)
问: 有人可以解释为什么重复这些值。
答:为了更好地理解重复值的原因,请运行不带GROUP_CONCAT
和GROUP BY
的查询。然后您的查询产生某种笛卡尔积:因为每个教师和每个翻译在结果中都有两种语言,您将获得所有可能的组合:
teacher_languages translator_languages ----------------- -------------------- English English English French French English French French
GROUP_CONCAT
只需连接所有列值即可获得:
[teacher_languages] => 'English, English, French, French'
[translator_languages] => 'English, French, English, French'
避免重复的可能解决方案之一是使用子查询:
SELECT
u.*,
a.teacher_languages, a.teacher_languages_status, a.teacher_language_views,
b.translator_languages, b.translator_languages_status, b.translator_language_views
FROM users u
LEFT JOIN (
SELECT
t.user_id,
-- teacher languages
GROUP_CONCAT(tl_txt.language_text) AS teacher_languages,
GROUP_CONCAT(tl.status) AS teacher_languages_status,
GROUP_CONCAT(tl.views) AS teacher_language_views
FROM teachers t
LEFT JOIN teacher_languages tl ON tl.teacher_id = t.id
LEFT JOIN languages tl_txt ON tl_txt.id = tl.language_id
GROUP BY t.user_id
) a ON a.user_id = u.id
LEFT JOIN (
SELECT
tr.user_id,
-- translator languages
GROUP_CONCAT(trl_txt.language_text) AS translator_languages,
GROUP_CONCAT(trl.status) AS translator_languages_status,
GROUP_CONCAT(trl.views) AS translator_language_views
FROM translators tr
LEFT JOIN translator_languages trl ON trl.teacher_id = tr.id
LEFT JOIN languages trl_txt ON trl_txt.id = trl.language_id
GROUP BY tr.user_id
) b ON b.user_id = u.id
ORDER BY u.created_at