【问题标题】:SQL : select top 4 results with the higher votes UP and lower votes DOWNSQL : 选择票数最高的前 4 个结果,票数较低的结果
【发布时间】:2015-12-24 07:57:38
【问题描述】:

我喜欢做一些简单的事情,但我不知道从哪里开始。

所以我有 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?

【问题讨论】:

  • 你的意思是你想要 8 条记录:4 个最高的赞成票,然后是 4 个最低的反对票?
  • 加入+联合+限制
  • @amdixon 不,我只想要 4 个,每个赞成票给 1 分,每个反对票减 1 分,我希望前 4 个分数更高
  • @VR46 是的,谢谢,但我不是 sql 专家
  • 我建议将您的投票重组为一张桌子

标签: mysql sql


【解决方案1】:

计划

  • 获取按每个行业分组的赞成票数
  • 获取按每个行业分组的反对票数
  • 将所有 trad 左连接到具有评分函数、排序依据和限制为 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 )

【讨论】:

  • 非常感谢 amdixon!是的,我将重组以制作一个单一的投票表
  • 不用担心 - 还使用组合投票表添加了小提琴
  • 完美,谢谢amdixon,我会把你的答案标记为最佳答案
  • 其中 id_question = $id_question before order by 丢失
【解决方案2】:

获得票数较高的前四个翻译;使用键连接表,然后按 up_votes 的升序排列,down_votes 的降序排列,然后通过 ROWNUM

【讨论】:

  • 我终于会采取amdixon的解决方案了,还是谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
相关资源
最近更新 更多