MySQL 排序解决方案:它能够保持一致性工作吗?

3

I had this query:

SELECT `name`, floor(max(score)), skill
FROM
  (SELECT k.`name`, s.`name` as skill, *long complex formula* as score
  FROM `keywords_skills` ks
  JOIN keywords k        ON k.id = ks.keyword_id
  JOIN skills s          ON s.id = ks.skill_id
  JOIN jobs_keywords jk  ON jk.keyword_id = k.id
  WHERE job_id = 87293) t1
GROUP BY `name`
ORDER BY `name` asc

显然我希望 'skill' 引用与 max(score) 相同的行,但我不知道如何实现。然而,当我在子查询中添加 ORDER BY 如下:

SELECT `name`, floor(max(score)), skill
FROM
  (SELECT k.`name`, s.`name` as skill, *long complex formula* as score
  FROM `keywords_skills` ks
  JOIN keywords k        ON k.id = ks.keyword_id
  JOIN skills s          ON s.id = ks.skill_id
  JOIN jobs_keywords jk  ON jk.keyword_id = k.id
  WHERE job_id = 87293
  ORDER BY score DESC) t1
GROUP BY `name`
ORDER BY `name` asc

一切似乎运作得很好!我的问题是:我解决了问题还是只是实现了一个不可靠的hack,以后会困扰我?
编辑:也许我应该更详细地解释一下我正在寻找什么:
关键词和技能之间具有多对多的关系。我不仅仅是寻找最高分数的关键词,而是每个关键词的最高分数的技能。
我还认为我可以在子查询中以某种方式使用LIMIT 1,但到目前为止,我还没有想到实现它的方法。
1个回答

2

我认为你的第一个答案已经很接近了……只需在排序语句后添加LIMIT 1,将最高技能放在第一位(按列3进行排序,这是您的得分公式)。

-- 根据修订的澄清... 我会按照问题中工作ID的层次结构重新排列查询,然后查找IT技能和关键字,而不是依赖关键字技能。在您所需要的情况下,您确实需要一个嵌套查询...例如:

Job A has Keywords
   Word A
       Skill A-1    Score:90  (you want this one)
       Skill A-2    Score:70
       Skill A-3    Score:60
   Word B 
       Skill B-1    Score:30
       Skill B-2    Score:20
       Skill B-3    Score:95  (you want this one)
       Skill B-4    Score:80
   Word C 
       Skill C-1    Score:10
       Skill C-2    Score:20
       Skill C-3    Score:30  (you want this one)

内部查询应该仅包括关键字id和关键字的最高分数 - 与一个Job_ID相关联。然后再次重新连接,但这一次我们不再需要job_keywords,因为每个K.ID和名称描述都在预查询中。然后,只需重新加入以符合合格分数的技能即可。
SELECT STRAIGHT_JOIN
      PreQuery.Keyword, 
      s.name as Skill, 
      PreQuery.Score
   from
      ( SELECT STRAIGHT_JOIN
              k.id,
              k.name Keyword, 
              max( s.Score ) maxScore
           from
              jobs_keywords jk
                 join keywords k 
                    on jk.keyword_id = k.id
                    join keyword_skills ks
                       on k.id = ks.keyword_id
                       join skills s
                          on ks.skill_id = s.id
           where 
              jk.job_id = 87293
           group by 
              k.id,
              k.name ) PreQuery
      join keyword_skills ks
         on PreQuery.id = ks.keyword_id
         join skills s
             on ks.skill_id = s.id
             AND PreQuery.maxScore = s.Score
   order by 
      PreQuery.Keyword

把那个子查询去掉,加上一个限制条件,就可以了。记住,如果你使用GROUP BY,不能保证得到的是最高分数,而这正是你要寻找的。 - Jay
好的解决方案,但是针对的是不同于我遇到的问题。我在原来的问题中添加了澄清…… - jisaacstone
@JIStone,修订后的答案包括复杂子查询。 - DRapp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接