Mysql 返回每个成员的顶部字段的SQL查询

Mysql 返回每个成员的顶部字段的SQL查询,mysql,sql,Mysql,Sql,假设我有一个包含以下字段的表 MEMBER_ID (text) CATEGORY1 (int) CATEGORY2 (int) CATEGORY3 (int) CATEGORY4 (int) …假设我有30多个类别字段,所有字段都相应编号。在每个类别字段中,都有一个数字分数 是否有一个查询可用于填充一个新表,该表看起来如此 会员身份证 TOP_CATEGORY上一个表中的类别名称 此成员ID的最高分数 SECOND_CATEGORY上一个表中的类别名称 此成员ID的第二高分 第三

假设我有一个包含以下字段的表

MEMBER_ID (text) 

CATEGORY1 (int) 

CATEGORY2 (int) 

CATEGORY3 (int)

CATEGORY4 (int)
…假设我有30多个类别字段,所有字段都相应编号。在每个类别字段中,都有一个数字分数

是否有一个查询可用于填充一个新表,该表看起来如此

会员身份证

TOP_CATEGORY上一个表中的类别名称 此成员ID的最高分数

SECOND_CATEGORY上一个表中的类别名称 此成员ID的第二高分

第三个类别上一个表中的类别名称 此成员ID的第三高分数


…我知道我可以使用这个用例,但如果我有大量的类别字段,我想这会变得很难处理。我还有其他选择吗?

在我看来,您最好的选择是规范化您的数据库结构。按成员和类别创建成员表、类别表和分数表。标准化后,您试图解决的问题将成为每组前n个问题,然后是条件聚合。例如,如果您遵循我在中创建的规范化模板,您的查询将如下所示:

select member_id,
       max(case when `rank` = 1 then name end) as top_category,
       max(case when `rank` = 2 then name end) as second_category,
       max(case when `rank` = 3 then name end) as third_category
from (select n.member_id, c.name, s1.score, count(s2.score) + 1 as rank
      from score s1
      left join score s2 on s2.member = s1.member and s1.score < s2.score
      join new_members n on n.id = s1.member
      join category c on c.id = s1.category
      group by n.member_id, c.name, s1.score
      having count(s2.score) < 3) s
group by member_id

数据库正常化后,添加新成员、类别和分数会变得容易得多,而用于获取数据的查询(如上述)根本不需要更改。

如果您有关系,则几乎不可能使用case表达式。谢谢!这看起来很完美。谢谢你的帮助。@JeffClayton不用担心。我很高兴能帮上忙。如果这确实解决了你的问题,请考虑标记答案接受在上/下投票箭头下的复选标记。看到可能的愚蠢问题。。。对于最后一个查询,如果我使用这样的东西,我会丢失任何重要的东西吗?它似乎和你的版本大致相同,但我觉得可能有些东西我没有解释。。。选择MBR\u ID,当秩=1时选择maxcase,然后将end命名为第一个\u类别,当秩=2时选择maxcase,然后将end命名为第二个\u类别,当秩=3时选择maxcase,然后将end命名为第三个\u类别_ID@JeffClayton点击分数是多少?啊,对不起。。。Click_Scores是带有MBR_ID、名称、分数和排名字段的表。