【问题标题】:GROUP BY and GROUP_CONCAT - how to return correct values?GROUP BY 和 GROUP_CONCAT - 如何返回正确的值?
【发布时间】:2011-10-31 16:21:27
【问题描述】:

我有以下疑问:

SELECT ev.q1, ev.comments, es.session_number, es.title, CONCAT( np.first_name,  ' ', np.last_name ) AS speaker
FROM  `expo_session_eval` ev
LEFT JOIN expo_session es ON es.session_id = ev.session_id
LEFT JOIN expo_session_speaker ess ON ess.session_id = ev.session_id
LEFT JOIN expo_speaker sp ON sp.speaker_id = ess.speaker_id
LEFT JOIN new_people np ON np.id = sp.people_id
GROUP BY CONCAT( np.first_name,  ' ', np.last_name ) 
ORDER BY es.session_number

这会返回如下所示的数据:

session_id  q1  comments    session_number  title               speaker
===================================================================================
169         3   Good!       103            Digital Practices      Steve Bullock
169         3   Good!       103            Digital Practices      Sheila Bacon
170         1               104            LBS = Location Based   Patrick Moorhead

这是正确的,因为在 expo_session_eval 中有两条记录为 session_id 169,但它是不正确的,因为 q1 和 cmets 值不相同。 expo_session_speaker 中有两条记录对应 session_id 169 - 即这一会话有两个发言者。

理想情况下,我希望我的结果如下所示:

session_id  q1  comments    session_number  title                  speaker
===============================================================================================
169         3   Good!       103            Digital Practices        Steve Bullock, Sheila Bacon
169         5   Great!      103            Digital Practices        Steve Bullock, Sheila Bacon
170         1               104            LBS = Location Based     Patrick Moorhead

我尝试过使用 GROUP_CONCAT,但显然我没有正确使用它,因为当我使用这个查询时:

SELECT ev.session_id, ev.q1, ev.comments, es.session_number, es.title, GROUP_CONCAT( CONCAT( np.first_name,  ' ', np.last_name ) ) AS speaker
FROM  `expo_session_eval` ev
LEFT JOIN expo_session es ON es.session_id = ev.session_id
LEFT JOIN expo_session_speaker ess ON ess.session_id = ev.session_id
LEFT JOIN expo_speaker sp ON sp.speaker_id = ess.speaker_id
LEFT JOIN new_people np ON np.id = sp.people_id
ORDER BY es.session_number

我明白了:

session_id  q1  comments    session_number  title                  speaker
===============================================================================================
169         3   Good!       103         Digital Practices   Steve Bullock,Sheila Bacon,Patrick Moorhead

我需要做什么才能在 session_id 中创建演讲者列 group_concat?

为@NOAH 编辑

主表是 expo_session_eval - 每条记录都有一个 session_id 存储。这些 ID 来自名为 expo_session 的表。有一个名为 expo_session_speaker 的交叉引用表,它只包含两列 - session_id 和 speaker_id。还有一个名为speaker_id 的表,其中包含speaker_id 和people_id。 people_id 将该表链接到一个名为 new_people 的表,该表包含 first_name 和 last_name。

在 expo_session_speaker 中,一个给定的 session_id 可以有多个记录 - 每个记录对应一个会话和一个发言者。因此,要显示给定会话的所有发言者,您最终会得到多条记录。这就是 group by/group_concat 的想法出现的地方;我需要在该会话的所有记录中显示给定会话的所有发言人。因此,会话 169 记录 1 的发言者是 Steve Bullock、Sheila Bacon,会话 169 记录 2 的发言者是相同的,即使两个会话 169 记录的其他选定值都不相同。

(清如泥,对吧?)

【问题讨论】:

  • 尝试将 GROUP BY ev.session_id 添加到您的查询中
  • @EmmyS - 可能只是我,但看起来您实际上想按 ev.q1 值和 session_id 分组?对吗?
  • 我尝试将它添加到我现有的 GROUP BY 语句中并代替它。两者都不返回所需的结果。我正在编辑 OP 以显示两者。
  • @NoahGoodrich - 不,不是真的。我减少了查询以使其更易于显示;实际上有 20 个 q 列(q1、q2 等),所以我不想按该值分组。我想要的是单独显示 expo_session_eval 中的所有记录,并连接相应的扬声器信息(通过 expo_speaker 中的扬声器 ID 链接的 new_people 中的 first_name、last_name)。这是一种复杂的表格设置,但出于某种原因,我不能仅仅为了这个特殊的需要而简化。编辑 OP 以解释表关系...

标签: mysql group-by group-concat


【解决方案1】:

您应该按session_id 分组(而不是排序)

SELECT ev.session_id, ev.q1, ev.comments, es.session_number, es.title, GROUP_CONCAT(  CONCAT( np.first_name,  ' ', np.last_name ) ) AS speaker
FROM  `expo_session_eval` ev
LEFT JOIN expo_session es ON es.session_id = ev.session_id
LEFT JOIN expo_session_speaker ess ON ess.session_id = ev.session_id
LEFT JOIN expo_speaker sp ON sp.speaker_id = ess.speaker_id
LEFT JOIN new_people np ON np.id = sp.people_id
GROUP BY ev.session_id

【讨论】:

  • 基于哪个版本的查询?使用 group_concat 的那个,还是没有使用 group_concat 的那个?除了按 first_name/last_name 分组,还是按 session_id 分组?
【解决方案2】:

这样的事情应该做你想做的事-

SELECT ev.session_id, ev.q1, ev.comments, es.session_number, es.title, speaker
FROM  `expo_session_eval` ev
LEFT JOIN expo_session es ON es.session_id = ev.session_id
LEFT JOIN (
    SELECT ess.session_id, GROUP_CONCAT( CONCAT( np.first_name,  ' ', np.last_name ) ) AS speaker
    FROM new_people np
    LEFT JOIN expo_speaker sp ON  np.id = sp.people_id
    LEFT JOIN expo_session_speaker ess ON sp.speaker_id = ess.speaker_id
    GROUP BY ess.session_id
) np ON np.session_id = es.session_id   
ORDER BY es.session_number

您实际上并不想在整个结果集上使用 GROUP BY 语句,只是为了创建连接的扬声器字符串,因此需要在子查询中完成。

【讨论】:

  • 这行得通,虽然它需要 45 秒才能完成(OP 中的其他两个半工作版本每个都需要不到 2 秒。)我想我需要做一些表格优化......
猜你喜欢
  • 1970-01-01
  • 2014-05-08
  • 2020-06-16
  • 2011-04-17
  • 2018-01-24
  • 2018-01-30
  • 2017-07-15
  • 2013-12-18
  • 2011-07-22
相关资源
最近更新 更多