根据条件从多个表中获取数据

问题描述 投票:1回答:1

我需要从3个不同的mysql表中获取一些数据,如下所示。

 +-----------------------------------+      
 | Questions                         |      
 -------------------------------------      
 | id: int(8)                        |      
 | -- data we don't care about here  |      
 | question: TEXT                    |      
 +-----------------------------------+    

 +--------------------------+               
 |Answers                   |               
 +--------------------------+               
 | id: int(8)               |               
 | -- other data            |               
 | answer: TEXT             |               
 +--------------------------+    

 +-----------------------------------+      
 |Votes                              |      
 +-----------------------------------+      
 | id: int(8)                        |      
 | step: tinyint(1)                  |      
 | answerId: int(8)                  |      
 +-----------------------------------+      

我需要获得每个问题的票数最多的答案,以及该答案所拥有的票数。

我能提出的最佳查询是:

SELECT question, answer, count(votes.id) votesCount FROM questions INNER JOIN answers ON questions.id = answers.questionId INNER JOIN votes ON answers.id = votes.answerId;

但是这是错误的,因为它总是返回带有第一个问题,一个随机答案和总票数的单个结果。

mysql sql count greatest-n-per-group window-functions
1个回答
0
投票

您的直接问题是您的查询缺少group by子句。因此,它仅返回一行,并具有总票数和任意选择的问题和答案。

如果您正在运行MySQL 8.0,则可以使用聚合和窗口功能轻松完成此操作:

select question, answer, votescount
from (
    select 
        q.question, 
        a.answer, 
        count(*) votescount,
        rank() over(partition by q.id order by count(*) desc) rn
    from questions q
    inner join answers a on q.id = a.questionid 
    inner join votes on a.id = v.answerid
    group by q.id, q.question, a.id, a.answer
) t
where rn = 1

在早期版本中,它有点复杂。一种选择是使用having子句过滤汇总结果集,该子句返回每个组的最高计数:

select 
    q.question, 
    a.answer, 
    count(*) votescount,
    rank() over(partition by q.id order by count(*) desc) rn
from questions q
inner join answers a on q.id = a.questionid 
inner join votes on a.id = v.answerid
group by q.id, q.question, a.id, a.answer
having count(*) = (
    select count(*)
    from answers a1
    inner join votes v1 a1.id = v1.answerid
    where a1.questionid = q.id
    group by a1.id
    order by count(*) desc
    limit 1
)
© www.soinside.com 2019 - 2024. All rights reserved.