SQL:选择前4个结果,选票越高,选票越低

时间:2015-12-24 07:57:39

标签: mysql sql

我想做的很简单,但我不知道从哪里开始。

所以我有4张桌子:

  
      
  • 表格问题(id_question)
  •   
  • 表格传输(id_trad,#id_question)
  •   
  • 表vote_up(id_vote_up,#id_trad)
  •   
  • 表vote_down(id_vote_down,#id_trad)
  •   

对于id_question = 1,我想选择4个翻译(来自传统)具有更高的vote_up数和更低的vote_down数

是否可以使用单个查询执行此操作?有什么想法吗?

或者最好简单地添加“upvotes”和“downvotes”并将相应字段更新为1?

2 个答案:

答案 0 :(得分:2)

<强>计划

  
      
  • 获得按每个传统分组的赞成票数
  •   
  • 获得按每个传统分组的downvotes数量
  •   
  • 将所有传统连接到具有得分函数的上述数据源,订购依据和限制为4
  •   

示例输入

create table question
(
  id_question integer primary key not null
  -- other metadata here..
);

create table trad
(
  id_trad integer primary key not null,
  id_question integer not null,
  foreign key ( id_question ) references question ( id_question )
);

create table vote_up
(
  id_vote_up integer primary key not null,
  id_trad integer not null,
  foreign key ( id_trad ) references trad ( id_trad )
);

create table vote_down
(
  id_vote_down integer primary key not null,
  id_trad integer not null,
  foreign key ( id_trad ) references trad ( id_trad )
);

insert into question
( id_question )
values
( 1 )
;

insert into trad
( id_trad, id_question )
values
( 1, 1 ),
( 2, 1 ),
( 3, 1 ),
( 4, 1 ),
( 5, 1 ),
( 6, 1 ),
( 7, 1 )
;

insert into vote_up
( id_vote_up, id_trad )
values
( 1, 1 ),
( 2, 1 ),
( 3, 1 ),
( 4, 1 ),
( 5, 1 ),
( 6, 1 ),
( 7, 3 ),
( 8, 3 ),
( 9, 3 ),
( 10, 3 ),
( 11, 4 ),
( 12, 4 ),
( 13, 5 ),
( 14, 6 ),
( 15, 6 ),
( 16, 7 ),
( 17, 7 ),
( 18, 7 )
;

insert into vote_down
( id_vote_down, id_trad )
values
( 1, 1 ),
( 2, 1 ),
( 3, 1 ),
( 4, 1 ),
( 5, 1 ),
( 6, 1 ),
( 7, 3 ),
( 8, 3 ),
( 9, 3 ),
( 10, 4 ),
( 11, 4 )
;

<强>查询

select trad.id_trad, coalesce(upvotes, 0) - coalesce(downvotes, 0) as score
from trad
left join
(
select 
trad.id_trad, count(*) as upvotes
from trad
inner join vote_up
on trad.id_trad = vote_up.id_trad
group by 1
) uv
on trad.id_trad = uv.id_trad
left join
(
select 
trad.id_trad, count(*) as downvotes
from trad
inner join vote_down
on trad.id_trad = vote_down.id_trad
group by 1
) dv
on uv.id_trad = dv.id_trad
where trad.id_question = 1
order by score desc
limit 4
;

<强>输出

+---------+-------+
| id_trad | score |
+---------+-------+
|       7 |     3 |
|       6 |     2 |
|       3 |     1 |
|       5 |     1 |
+---------+-------+

<强> sqlfiddle ( separate structures )

注意

  

考虑将您的投票重组为一个表格。 atm vote_up和   vote_down不必要地重复相同的结构..   这看起来像是:

<强> sqlfiddle ( reuse structure )

答案 1 :(得分:0)

使用更高的赞成票获得前四个翻译;使用键连接表,然后按up_votes的升序排序,按降序排序他们的down_votes,然后通过执行ROWNUM&lt; = 4来获得前四次转换。