如何获得最后和第二次记录。以及如何在子查询中使用它。?

时间:2017-04-24 10:39:54

标签: mysql logic

+----+-------------------------+--------+------------+-------+--------+--------------+------------+
| id |        user_email       | cat_id | sub_cat_id | score | out_of | score_in_per | date       |
+----+-------------------------+--------+------------+-------+--------+--------------+------------+
| 13 | inststudent@yopmail.com | 9      | 11         | 40    | 40     | 100          | 22-04-2017 |
+----+-------------------------+--------+------------+-------+--------+--------------+------------+
| 14 | inststudent@yopmail.com | 9      | 11         | 37    | 40     | 92.5         | 22-04-2017 |
+----+-------------------------+--------+------------+-------+--------+--------------+------------+
| 26 | inststudent@yopmail.com | 9      | 11         | 36    | 40     | 88           | 23-04-2017 |
+----+-------------------------+--------+------------+-------+--------+--------------+------------+
| 27 | inststudent@yopmail.com | 9      | 11         | 35    | 40     | 80           | 23-04-2017 |
+----+-------------------------+--------+------------+-------+--------+--------------+------------+

从上表我想得到这样的记录,任何人都可以帮助我/

+-----------+-----------------+---------------+-------------------------+--------+------------+-------+--------+--------------+------+
| lastScore | secondLastScore | maxPortaScore |        user_email       | cat_id | sub_cat_id | score | out_of | score_in_per | date |
+-----------+-----------------+---------------+-------------------------+--------+------------+-------+--------+--------------+------+
| 80        | 88              | 100           | inststudent@yopmail.com | 9      | 11         | -     | -      | -            | -    |
+-----------+-----------------+---------------+-------------------------+--------+------------+-------+--------+--------------+------+

这是我的疑问:

SELECT 
scor.id,
(SELECT score_in_per 
FROM tbl_student_skill_score 
WHERE cat_id = scor.cat_id and sub_cat_id = scor.sub_cat_id and scor.user_email='inststudent@yopmail.com'
ORDER BY scor.date DESC,scor.id DESC LIMIT 1)
as lastScore,

(SELECT score_in_per 
FROM tbl_student_skill_score
WHERE cat_id=scor.cat_id and sub_cat_id=scor.sub_cat_id and scor.user_email='inststudent@yopmail.com' 
ORDER BY scor.date DESC,scor.id DESC LIMIT 1,1)
as secondLastScore,

(SELECT max(cast(score_in_per as decimal(5,2))) 
FROM tbl_student_skill_score 
WHERE cat_id = scor.cat_id and sub_cat_id=scor.sub_cat_id) 
as maxPortaScore,

scor.user_email,scor.cat_id,
scor.sub_cat_id,scor.score, scor.out_of,
scor.score_in_per,scor.date
FROM 
tbl_student_skill_score scor 
LEFT JOIN 
tbl_skilltest_subcategory subc 
ON 
scor .sub_cat_id = subc.scat_id 
LEFT JOIN 
tbl_skilltest_category catg 
ON subc.cat_id = catg.id 
where 
scor.user_email = 'inststudent@yopmail.com'
GROUP BY 
sub_cat_id 
ORDER by 
scor.id DESC,scor.date DESC

形成上述查询 lastScore secondLastScore 无效

lastScore 表示我的案例中最后一个存储的记录来自第一个表id:27记录。所以结果应该 80

类似地

secondLastScore 表示我的案例中第二个最后存储的记录来自第一个表id:26记录。所以结果应该是 88

maxPortaScore 表示整个表格中特定类别的最高分数,与我的情况下的特定学生无关 100 我使用了相同的用户,但实际上它可以是任何用户分数。 [这是工作绝对精细]

2 个答案:

答案 0 :(得分:1)

您可以分三步完成:首先,您获得每个用户的最后一个ID和最高分

select  user_email, max(id) max_id, max(score_in_per) max_score
from    tbl_student_skill_score
group by user_email

然后通过使用上述查询

加入表格,获得第二个最后一个ID
select  t2.max_id, max(id) as second_max, t2.max_score, user_email
from    tbl_student_skill_score t1
right join (
            select  user_email, max(id) max_id, max(score_in_per) max_score
            from    tbl_student_skill_score
            group by user_email
        ) t2
on      t1.user_email = t2.user_email
where   t1.id < t2.max_id
group by user_email

最后,您可以将所有这些加入原始表格,以获取类别信息以及与上一个和后一个最后一个ID相关联的分数

select  t2.score_in_per as lastScore,
        t3.score_in_per as secondLastScore,
        t1.max_score as maxPortaScore,
        t2.user_email,
        t2.cat_id,
        t2.sub_cat_id
from    (
            select  t2.max_id, max(id) as second_max, t2.max_score, user_email
            from    tbl_student_skill_score t1
            right join (
                        select  user_email, max(id) max_id, max(score_in_per) max_score
                        from    tbl_student_skill_score
                        group by user_email
                    ) t2
            on      t1.user_email = t2.user_email
            where   t1.id < t2.max_id
            group by user_email
        ) t1
join    tbl_student_skill_score t2
on      t1.user_email = t2.user_email and
        t1.max_id = t2.id
left join
        tbl_student_skill_score t3
on      t1.user_email = t3.user_email and
        t1.second_max = t3.id

答案 1 :(得分:1)

这个查询似乎有点复杂,在这里我选择使用更少的连接来执行此操作:

select
    (
        select t1.score_in_per
        from tbl_student_skill_score t1
        where t1.user_email = t.user_email
        and t1.cat_id = t.cat_id
        and t1.sub_cat_id = t.sub_cat_id
        and t1.id = max(t.id) -- this will get the max(id) record in each group
        limit 1
    ) lastScore,
    (
        select t1.score_in_per
        from tbl_student_skill_score t1
        where t1.user_email = t.user_email
        and t1.cat_id = t.cat_id
        and t1.sub_cat_id = t.sub_cat_id
        and t1.id < max(t.id) -- this will get all the record which id less than max(id), then use `order by t1.id desc limit 1`, of course the second last record will be retrieved.
        order by t1.id desc
        limit 1
    ) secondLastScore,
    max(score_in_per) as maxPortaScore,
    user_email, `cat_id`, `sub_cat_id`
from tbl_student_skill_score t
group by `user_email`, `cat_id`, `sub_cat_id`

其他一些联接,您应该自己添加它们 如果每个组中只有一条记录,则secondLastScore将为NULL