MySQL:通过选择每组中的前两行进行分组

时间:2017-05-11 09:27:50

标签: mysql sql

有没有办法从答案表中为每个Q选择前2个答案:

user_answers表结构:

id    question_id    user_id    answer_id    create_date
1         1             9           5            null
2         2             8           7            null
3         1             1           3            null
4         3             4           20           null
5         1             4           5            null
6         4             3           25           null
7         2             7           5            null
8         4             9           26           null
9         2             5           8            null
10        1             1           5            null

我需要返回这样的结果:

id    question_id    user_id    answer_id    create_date
1         1             9           5            null
3         1             1           3            null
2         2             8           7            null
7         2             7           5            null
4         3             4           20           null
6         4             3           25           null
8         4             9           26           null

它就像Group by" question_id"但是从每个组中选择前两行

感谢,

3 个答案:

答案 0 :(得分:2)

这是一个规范问题,其中ROW_NUMBER分析函数非常有用。 MySQL不支持开箱即用的任何行号功能,但我们可以使用会话变量来模拟它:

SET @row_num = 0;
SET @q_id = 0;

SELECT
    t.id,
    t.question_id,
    t.user_id,
    t.answer_id,
    t.create_date
FROM
(
    SELECT 
        @row_num:=CASE WHEN @q_id = question_id THEN @row_num + 1 ELSE 1 END AS rn,
        @q_id:=question_id as question_id,
        id,
        user_id,
        answer_id,
        create_date
    FROM
        user_answers
    ORDER BY question_id, id
) t
WHERE t.rn <= 2
ORDER BY t.question_id, t.id;

<强>输出:

enter image description here

在这里演示:

Rextester

答案 1 :(得分:1)

有一个简单但相当慢的解决方案:计算记录。

select *
from answers
where
(
  select count(*)
  from mytable other
  where other.questionid = answers.questionid
  and other.id <= answers.id
) <= 2
order by questionid, id;

答案 2 :(得分:1)

一种方法:(如果每组需要超过2行,那么这不是解决方案)

select your_table.* from your_table
inner join(
    select min(id) as id from your_table group by question_id
    union all
    select min(id) as id from your_table
    where id not in (select min(id) from your_table group by question_id)
    group by question_id
) t
on your_table.id = t.id
order by your_table.question_id , your_table.id