使用GROUP BY时优先考虑WHERE IN()

时间:2014-08-20 10:37:15

标签: mysql case

我有一个表格结构,将演讲者演示文稿相关联,可能是后者的多个。

我们为每个演示文稿提供直播待机建议的状态。

当我提取所有数据(演讲者/演示文稿)时,我会按照扬声器分组和排序,因此每个只按字母顺序出现一次,但我需要优先考虑附加到哪个状态那个演讲者。

优先顺序是1)直播,2)待机,3)建议(因此,如果发言人有一个现场演示和一个待机演示,他们将被拉出状态直播。

我在订购这些状态时遇到了麻烦,但我相信我需要CASE构造。

这是我的测试查询,只使用一个扬声器(为简单起见),分配了三个演示文稿,每个状态一个:

SELECT speaker_id, presentation_id, presentation_status 
FROM conf_presentation
INNER JOIN spk_pres USING(presentation_id) 
WHERE presentation_status IN('live','proposed','standby')
CASE
    WHEN presentation_status = 'live' THEN my_order = 1
    WHEN presentation_status = 'standby' THEN my_order = 2
    WHEN presentation_status = 'proposed' THEN my_order = 3
AND speaker_id = 16551
GROUP BY speaker_id
ORDER BY my_order

它目前在某处出现语法错误,即使修复了这一点,我也不确定这是否是我想做的事情。

我的预期结果如下:

SPEAKER  PRESENTATION  STATUS
16551    20113         live

由于没有任何CASE,将返回此演讲者表格中的第一个演示文稿:

SPEAKER  PRESENTATION  STATUS
16551    20227         proposed

2 个答案:

答案 0 :(得分:1)

这是一个能够控制在每组中选择的结果的顺序的情况。 Mysql没有办法直接做到这一点。有很多方法可以解决它...... https://www.google.com/search?q=mysql+within+group+order+by

我个人最喜欢的是使用GROUP_CONCAT - 因为它允许订购。然后使用SUBSTRING_INDEX来提取第一个。 (并避免复杂的子查询)

SELECT speaker_id, 
    SUBSTRING_INDEX(GROUP_CONCAT(presentation_id ORDER BY FIELD(presentation_status, 'live', 'standby', 'proposed') ASC),',',1) AS presentation_id, 
    SUBSTRING_INDEX(GROUP_CONCAT(presentation_status ORDER BY FIELD(presentation_status, 'live', 'standby', 'proposed') ASC),',',1) AS presentation_status
FROM conf_presentation
INNER JOIN spk_pres USING(presentation_id) 
WHERE presentation_status IN('live','proposed','standby')
GROUP BY speaker_id

这使用了其他答案中提到的FIELD()函数。哪个比CASE好。

......但更好的方法是将presentation_status设为ENUM列。然后通过以正确的顺序放置值,可以按数字上下文顺序。例如,使用ENUM('live','proposed','standby')可以简单地执行

GROUP_CONCAT(presentation_id ORDER BY presentation_status+0 ASC)

这可以扩展到所有发言者。如果要选择最终订单,可以正常使用ORDER BY。

答案 1 :(得分:0)

优先级(如果很少更改)应该真正存储在presentation_status(presentation_id, title, priority)中的数据库中,并由spk_pres.presentation_id引用。

然后你可以ORDER BY spk_pres.speaker_id, presentation_status.priority

我还想在JOIN的查询中为每个列添加一个表别名(通常是表首字母),以便我可以看到每个列的来源,并避免冲突,单独阅读查询。在这里,我不得不猜测speaker_id来自哪里。