我有一个表格结构,将演讲者与演示文稿相关联,可能是后者的多个。
我们为每个演示文稿提供直播,待机或建议的状态。
当我提取所有数据(演讲者/演示文稿)时,我会按照扬声器分组和排序,因此每个只按字母顺序出现一次,但我需要优先考虑附加到哪个状态那个演讲者。
优先顺序是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
答案 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
来自哪里。