当前位置:网站首页>SQL advanced challenge (26 - 30)

SQL advanced challenge (26 - 30)

2022-06-21 07:07:00 Cun Yuyao

SQL26 Every 6/7 Level user activity

describe

Existing user information table user_info(uid user ID,nick_name nickname , achievement Achievement value , level Grade , job Career direction , register_time Registration time ):

iduidnick_nameachievementleveljobregister_time
11001 Cattle guest 1 Number 31007 Algorithm 2020-01-01 10:00:00
21002 Cattle guest 2 Number 23007 Algorithm 2020-01-01 10:00:00
31003 Cattle guest 3 Number 25007 Algorithm 2020-01-01 10:00:00
41004 Cattle guest 4 Number 12005 Algorithm 2020-01-01 10:00:00
51005 Cattle guest 5 Number 16006C++2020-01-01 10:00:00
61006 Cattle guest 6 Number 26007C++2020-01-01 10:00:00

Test paper information sheet examination_info(exam_id The examination paper ID, tag Test paper category , difficulty The difficulty of the test paper , duration The length of the exam , release_time Release time ):

idexam_idtagdifficultydurationrelease_time
19001SQLhard602021-09-01 06:00:00
29002C++easy602021-09-01 06:00:00
39003 Algorithm medium802021-09-01 10:00:00

Test paper answer record form exam_record(uid user ID, exam_id The examination paper ID, start_time Start answering time , submit_time Submission time , score score ):

uidexam_idstart_timesubmit_timescore
100190012021-09-01 09:01:012021-09-01 09:31:0078
100190012021-09-01 09:01:012021-09-01 09:31:0081
100590012021-09-01 19:01:012021-09-01 19:30:0185
100590022021-09-01 12:01:012021-09-01 12:31:0285
100690032021-09-07 10:01:012021-09-07 10:21:5984
100690012021-09-07 10:01:012021-09-07 10:21:0181
100290012020-09-01 13:01:012020-09-01 13:41:0181
100590012021-09-01 14:01:01(NULL)(NULL)

Title Exercise record sheet practice_record(uid user ID, question_id subject ID, submit_time Submission time , score score ):

uidquestion_idsubmit_timescore
100180012021-08-02 11:41:0160
100480012021-08-02 19:38:0170
100480022021-08-02 19:48:0190
100180022021-08-02 19:38:0170
100480022021-08-02 19:48:0190
100680022021-08-04 19:58:0194
100680032021-08-03 19:38:0170
100680032021-08-02 19:48:0190
100680032020-08-01 19:38:0180

problem

Please count each 6/7 Total active months of tier 1 users 、2021 Annual active days 、2021 The number of active days to answer the annual test paper 、2021 Number of active days of answering questions in the year , According to the total active months 、2021 The annual active days are sorted in descending order . The results of the sample data are output as follows :

uidact_month_totalact_days_2021act_days_2021_examact_days_2021_question
10063413
10012211
10051110
10021000
10030000

explain :6/7 Level users share 5 individual , among 1006 stay 202109、202108、202008 common 3 I have been active for months ,2021 The active dates of the year are 20210907、20210804、20210803、20210802 common 4 God ,2021 In the examination paper answering area 20210907 active 1 God , Active in the topic exercise area 3 God .

Example

 Input :
drop table if exists examination_info,user_info,exam_record,practice_record;
CREATE TABLE examination_info (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    exam_id int UNIQUE NOT NULL COMMENT ' The examination paper ID',
    tag varchar(32) COMMENT ' Category label ',
    difficulty varchar(8) COMMENT ' difficulty ',
    duration int NOT NULL COMMENT ' Duration ',
    release_time datetime COMMENT ' Release time '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE user_info (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int UNIQUE NOT NULL COMMENT ' user ID',
    `nick_name` varchar(64) COMMENT ' nickname ',
    achievement int COMMENT ' Achievement value ',
    level int COMMENT ' User level ',
    job varchar(32) COMMENT ' Career direction ',
    register_time datetime COMMENT ' Registration time '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE practice_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int NOT NULL COMMENT ' user ID',
    question_id int NOT NULL COMMENT ' subject ID',
    submit_time datetime COMMENT ' Submission time ',
    score tinyint COMMENT ' score '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int NOT NULL COMMENT ' user ID',
    exam_id int NOT NULL COMMENT ' The examination paper ID',
    start_time datetime NOT NULL COMMENT ' Starting time ',
    submit_time datetime COMMENT ' Submission time ',
    score tinyint COMMENT ' score '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO user_info(uid,`nick_name`,achievement,level,job,register_time) VALUES
  (1001, ' Cattle guest 1 Number ', 3100, 7, ' Algorithm ', '2020-01-01 10:00:00'),
  (1002, ' Cattle guest 2 Number ', 2300, 7, ' Algorithm ', '2020-01-01 10:00:00'),
  (1003, ' Cattle guest 3 Number ', 2500, 7, ' Algorithm ', '2020-01-01 10:00:00'),
  (1004, ' Cattle guest 4 Number ', 1200, 5, ' Algorithm ', '2020-01-01 10:00:00'),
  (1005, ' Cattle guest 5 Number ', 1600, 6, 'C++', '2020-01-01 10:00:00'),
  (1006, ' Cattle guest 6 Number ', 2600, 7, 'C++', '2020-01-01 10:00:00');

INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES
  (9001, 'SQL', 'hard', 60, '2021-09-01 06:00:00'),
  (9002, 'C++', 'easy', 60, '2021-09-01 06:00:00'),
  (9003, ' Algorithm ', 'medium', 80, '2021-09-01 10:00:00');

INSERT INTO practice_record(uid,question_id,submit_time,score) VALUES
(1001, 8001, '2021-08-02 11:41:01', 60),
(1004, 8001, '2021-08-02 19:38:01', 70),
(1004, 8002, '2021-08-02 19:48:01', 90),
(1001, 8002, '2021-08-02 19:38:01', 70),
(1004, 8002, '2021-08-02 19:48:01', 90),
(1006, 8002, '2021-08-04 19:58:01', 94),
(1006, 8003, '2021-08-03 19:38:01', 70),
(1006, 8003, '2021-08-02 19:48:01', 90),
(1006, 8003, '2020-08-01 19:38:01', 80);

INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1001, 9001, '2021-09-01 09:01:01', '2021-09-01 09:31:00', 78),
(1001, 9001, '2021-09-01 09:01:01', '2021-09-01 09:31:00', 81),
(1005, 9001, '2021-09-01 19:01:01', '2021-09-01 19:30:01', 85),
(1005, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:02', 85),
(1006, 9003, '2021-09-07 10:01:01', '2021-09-07 10:21:59', 84),
(1006, 9001, '2021-09-07 10:01:01', '2021-09-07 10:21:01', 81),
(1002, 9001, '2020-09-01 13:01:01', '2020-09-01 13:41:01', 81),
(1005, 9001, '2021-09-01 14:01:01', null, null);
 Output :
1006|3|4|1|3
1001|2|2|1|1
1005|1|1|1|0
1002|1|0|0|0
1003|0|0|0|0

answer

SELECT 
    ui.uid,
    COUNT(DISTINCT LEFT(s,6)) AS act_month_total,
    COUNT(DISTINCT IF(LEFT(s,4)='2021',RIGHT(s,4),null)) AS act_days_2021,
    COUNT(DISTINCT IF(LEFT(s,4)='2021' AND tag='e',RIGHT(s,4),null)) AS act_days_2021_exam,
    COUNT(DISTINCT IF(LEFT(s,4)='2021' AND tag='p',RIGHT(s,4),null)) AS act_days_2021_question
FROM (
        SELECT uid,DATE_FORMAT(submit_time,'%Y%m%d') AS s,'p' tag FROM practice_record pr
        UNION ALL
        SELECT uid,DATE_FORMAT(start_time,'%Y%m%d') AS s,'e' AS tag FROM exam_record er 
)mon
RIGHT JOIN user_info ui
ON ui.uid = mon.uid
WHERE ui.level >5
GROUP BY uid
ORDER BY act_month_total DESC,act_days_2021 DESC;

SQL27 Before the score of each type of test paper 3 name

describe

Existing test paper information table examination_info(exam_id The examination paper ID, tag Test paper category , difficulty The difficulty of the test paper , duration The length of the exam , release_time Release time ):

idexam_idtagdifficultydurationrelease_time
19001SQLhard602021-09-01 06:00:00
29002SQLhard602021-09-01 06:00:00
39003 Algorithm medium802021-09-01 10:00:00

Test paper answer record form exam_record(uid user ID, exam_id The examination paper ID, start_time Start answering time , submit_time Submission time , score score ):

iduidexam_idstart_timesubmit_timescore
1100190012021-09-01 09:01:012021-09-01 09:31:0078
2100290012021-09-01 09:01:012021-09-01 09:31:0081
3100290022021-09-01 12:01:012021-09-01 12:31:0181
4100390012021-09-01 19:01:012021-09-01 19:40:0186
5100390022021-09-01 12:01:012021-09-01 12:31:5189
6100490012021-09-01 19:01:012021-09-01 19:30:0185
7100590032021-09-01 12:01:012021-09-01 12:31:0285
8100690032021-09-07 10:01:012021-09-07 10:21:0184
9100390032021-09-08 12:01:012021-09-08 12:11:0140
10100390022021-09-01 14:01:01(NULL)(NULL)

problem

Find the top score of each type of test paper 3 name , If two people have the same maximum score , Choose the one with the lowest score or the higher one , If it's the same , choice uid The great . The results of the sample data are output as follows :

tiduidranking
SQL10031
SQL10042
SQL10023
Algorithm 10051
Algorithm 10062
Algorithm 10033

explain : A test paper with a score record tag Yes SQL Sum algorithm ,SQL Test paper users 1001、1002、1003、1004 There are scores , The highest scores were 81、81、89、85, The lowest scores are 78、81、86、40, Therefore, the top three are ranked by the highest score and then by the lowest score 1003、1004、1002.

Example

 Input :
drop table if exists examination_info,exam_record;
CREATE TABLE examination_info (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    exam_id int UNIQUE NOT NULL COMMENT ' The examination paper ID',
    tag varchar(32) COMMENT ' Category label ',
    difficulty varchar(8) COMMENT ' difficulty ',
    duration int NOT NULL COMMENT ' Duration ',
    release_time datetime COMMENT ' Release time '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int NOT NULL COMMENT ' user ID',
    exam_id int NOT NULL COMMENT ' The examination paper ID',
    start_time datetime NOT NULL COMMENT ' Starting time ',
    submit_time datetime COMMENT ' Submission time ',
    score tinyint COMMENT ' score '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES
  (9001, 'SQL', 'hard', 60, '2021-09-01 06:00:00'),
  (9002, 'SQL', 'hard', 60, '2021-09-01 06:00:00'),
  (9003, ' Algorithm ', 'medium', 80, '2021-09-01 10:00:00');

INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1001, 9001, '2021-09-01 09:01:01', '2021-09-01 09:31:00', 78),
(1001, 9001, '2021-09-01 09:01:01', '2021-09-01 09:31:00', 81),
(1002, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:01', 81),
(1003, 9001, '2021-09-01 19:01:01', '2021-09-01 19:40:01', 86),
(1003, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:51', 89),
(1004, 9001, '2021-09-01 19:01:01', '2021-09-01 19:30:01', 85),
(1005, 9003, '2021-09-01 12:01:01', '2021-09-01 12:31:02', 85),
(1006, 9003, '2021-09-07 10:01:01', '2021-09-07 10:21:01', 84),
(1003, 9003, '2021-09-08 12:01:01', '2021-09-08 12:11:01', 40),
(1003, 9002, '2021-09-01 14:01:01', null, null);
 Output :
SQL|1003|1
SQL|1004|2
SQL|1002|3
 Algorithm |1005|1
 Algorithm |1006|2
 Algorithm |1003|3

answer

First, filter out a result set of all kinds of tags, users and rankings .

SELECT tag, exam_record.uid,
    row_number() over (PARTITION BY tag ORDER BY tag, 
                       MAX(score) DESC, 
                       MIN(score) DESC, exam_record.uid DESC) ranking
    FROM exam_record JOIN examination_info
    ON exam_record.exam_id = examination_info.exam_id
    GROUP BY tag, exam_record.uid;

Then, from the result set, the ranking is not greater than 3 The label of 、 user ID And ranking , namely SELECT ... FROM ... WHERE....

SELECT tag, uid, ranking
FROM(
    SELECT tag, exam_record.uid,
    row_number() over (PARTITION BY tag ORDER BY tag, 
                       MAX(score) DESC, 
                       MIN(score) DESC, exam_record.uid DESC) ranking
    FROM exam_record JOIN examination_info
    ON exam_record.exam_id = examination_info.exam_id
    GROUP BY tag, exam_record.uid
) ranktable
WHERE ranking <= 3;

SQL28 Second, fast / The difference of slow time is more than half the length of the test paper

describe

Existing test paper information table examination_info(exam_id The examination paper ID, tag Test paper category , difficulty The difficulty of the test paper , duration The length of the exam , release_time Release time ):

idexam_idtagdifficultydurationrelease_time
19001SQLhard602021-09-01 06:00:00
29002C++hard602021-09-01 06:00:00
39003 Algorithm medium802021-09-01 10:00:00

Test paper answer record form exam_record(uid user ID, exam_id The examination paper ID, start_time Start answering time , submit_time Submission time , score score ):

iduidexam_idstart_timesubmit_timescore
1100190012021-09-01 09:01:012021-09-01 09:51:0178
2100190022021-09-01 09:01:012021-09-01 09:31:0081
3100290022021-09-01 12:01:012021-09-01 12:31:0181
4100390012021-09-01 19:01:012021-09-01 19:59:0186
5100390022021-09-01 12:01:012021-09-01 12:31:5189
6100490022021-09-01 19:01:012021-09-01 19:30:0185
7100590012021-09-01 12:01:012021-09-01 12:31:0285
8100690012021-09-07 10:01:012021-09-07 10:21:0184
9100390012021-09-08 12:01:012021-09-08 12:11:0140
10100390022021-09-01 14:01:01(NULL)(NULL)
11100590012021-09-01 14:01:01(NULL)(NULL)
12100390032021-09-08 15:01:01(NULL)(NULL)

problem

Find the test paper information that the difference between the second fast time and the second slow time is greater than half of the test paper time , According to the test paper ID null . The results of the sample data are output as follows :

exam_iddurationrelease_time
9001602021-09-01 06:00:00

explain : The examination paper 9001 When used as an answer, there are 50 minute 、50 minute 、30 branch 1 second 、11 minute 、10 minute , The difference between the second fast time and the second slow time is 50 minute -11 minute =39 minute , The length of the test paper is 60 minute , Therefore, it meets the condition that the test paper is longer than half , Output the test paper ID、 Duration 、 Release time .

Example

 Input :
drop table if exists examination_info,exam_record;
CREATE TABLE examination_info (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    exam_id int UNIQUE NOT NULL COMMENT ' The examination paper ID',
    tag varchar(32) COMMENT ' Category label ',
    difficulty varchar(8) COMMENT ' difficulty ',
    duration int NOT NULL COMMENT ' Duration ',
    release_time datetime COMMENT ' Release time '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int NOT NULL COMMENT ' user ID',
    exam_id int NOT NULL COMMENT ' The examination paper ID',
    start_time datetime NOT NULL COMMENT ' Starting time ',
    submit_time datetime COMMENT ' Submission time ',
    score tinyint COMMENT ' score '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES
  (9001, 'SQL', 'hard', 60, '2021-09-01 06:00:00'),
  (9002, 'C++', 'hard', 60, '2021-09-01 06:00:00'),
  (9003, ' Algorithm ', 'medium', 80, '2021-09-01 10:00:00');

INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1001, 9001, '2021-09-01 09:01:01', '2021-09-01 09:51:01', 78),
(1001, 9002, '2021-09-01 09:01:01', '2021-09-01 09:31:00', 81),
(1002, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:01', 81),
(1003, 9001, '2021-09-01 19:01:01', '2021-09-01 19:59:01', 86),
(1003, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:51', 89),
(1004, 9002, '2021-09-01 19:01:01', '2021-09-01 19:30:01', 85),
(1005, 9001, '2021-09-01 12:01:01', '2021-09-01 12:31:02', 85),
(1006, 9001, '2021-09-07 10:01:01', '2021-09-07 10:12:01', 84),
(1003, 9001, '2021-09-08 12:01:01', '2021-09-08 12:11:01', 40),
(1003, 9002, '2021-09-01 14:01:01', null, null),
(1005, 9001, '2021-09-01 14:01:01', null, null),
(1003, 9003, '2021-09-08 15:01:01', null, null);
 Output :
9001|60|2021-09-01 06:00:00

answer

Disassemble the topic according to the problem , First of all, count the time taken to complete the second fastest and the second slowest of each set of test papers and the information of the test papers .

SELECT exam_id, duration, release_time
FROM (
    SELECT DISTINCT exam_id, duration, release_time,
        NTH_VALUE(time_took, 2) OVER (
            PARTITION BY exam_id ORDER BY time_took DESC) as max2nd_time,
        NTH_VALUE(time_took, 2) OVER (
            PARTITION BY exam_id ORDER BY time_took ASC) as min2nd_time
    FROM (
        SELECT exam_id, duration, release_time,
            TimeStampDiff(SECOND, start_time, submit_time) / 60 as time_took
        FROM exam_record JOIN examination_info USING(exam_id)
        WHERE submit_time IS NOT NULL
    ) as exam_record_timetook
) as exam_time_took;

Then select the test paper whose difference between the second fast time and the second slow time is greater than half of the test paper time , namely WHERE max2nd_time - min2nd_time > duration / 2.

SELECT exam_id, duration, release_time
FROM (
    SELECT DISTINCT exam_id, duration, release_time,
        NTH_VALUE(time_took, 2) OVER (
            PARTITION BY exam_id ORDER BY time_took DESC) as max2nd_time,
        NTH_VALUE(time_took, 2) OVER (
            PARTITION BY exam_id ORDER BY time_took ASC) as min2nd_time
    FROM (
        SELECT exam_id, duration, release_time,
            TimeStampDiff(SECOND, start_time, submit_time) / 60 as time_took
        FROM exam_record JOIN examination_info USING(exam_id)
        WHERE submit_time IS NOT NULL
    ) as exam_record_timetook
) as exam_time_took
WHERE max2nd_time - min2nd_time > duration / 2
ORDER BY exam_id DESC;

SQL29 The maximum time window for answering the test paper twice in a row

describe

Existing test paper answer record form exam_record(uid user ID, exam_id The examination paper ID, start_time Start answering time , submit_time Submission time , score score ):

iduidexam_idstart_timesubmit_timescore
1100690032021-09-07 10:01:012021-09-07 10:21:0284
2100690012021-09-01 12:11:012021-09-01 12:31:0189
3100690022021-09-06 10:01:012021-09-06 10:21:0181
4100590022021-09-05 10:01:012021-09-05 10:21:0181
5100590012021-09-05 10:31:012021-09-05 10:51:0181

problem

Please calculate in 2021 Among those who have answered the examination paper for at least two days in , Calculate the maximum time window for answering the test paper for two consecutive times in the year days_window, Then, according to the historical law of that year, he was days_window How many sets of test papers will you do on average in a day , Sort in reverse order according to the maximum time window and the average number of test papers . The results of the sample data are output as follows :

uiddays_windowavg_exam_cnt
100662.57

explain : user 1006 Respectively in 20210901、20210906、20210907 Answered 3 Test paper , The maximum time window for two consecutive answers is 6 God (1 Number to 6 Number ), He 1 Number to 7 This is the number one 7 I did it all day 3 Papers , Average daily 3/7=0.428571 Zhang , that 6 On average, I do 0.428571*6=2.57 Papers ( Keep two decimal places );

user 1005 stay 20210905 Made two test papers , But only one day's answer record , To filter out .

Example

 Example 1
 Input :
drop table if exists exam_record;
CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int NOT NULL COMMENT ' user ID',
    exam_id int NOT NULL COMMENT ' The examination paper ID',
    start_time datetime NOT NULL COMMENT ' Starting time ',
    submit_time datetime COMMENT ' Submission time ',
    score tinyint COMMENT ' score '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1006, 9003, '2021-09-07 10:01:01', '2021-09-07 10:21:02', 84),
(1006, 9001, '2021-09-01 12:11:01', '2021-09-01 12:31:01', 89),
(1006, 9002, '2021-09-06 10:01:01', '2021-09-06 10:21:01', 81),
(1005, 9002, '2021-09-05 10:01:01', '2021-09-05 10:21:01', 81),
(1005, 9001, '2021-09-05 10:31:01', '2021-09-05 10:51:01', 81);
 Output :
1006|6|2.57

answer

  1. Statistics first 2021 Everyone's total answer in 、 The earliest and latest days apart 、 Maximum continuous answer interval .
SELECT uid,
        COUNT(start_time) exam_cnt,
        DATEDIFF(MAX(start_time), MIN(start_time)) + 1 diff_days, 
        MAX(DATEDIFF(next_start_time, start_time)) + 1 days_window
    FROM (
        SELECT uid, exam_id, start_time,
            lead(start_time) over(
                PARTITION BY uid ORDER BY start_time) next_start_time
        FROM exam_record
        WHERE YEAR(start_time)=2021
    ) exam_record_lead
    GROUP BY uid;
  1. Then, the earliest and the latest ones with an interval greater than 1 A record of days , namely WHERE diff_days > 1.
  2. Finally, calculate the average number of test papers that can be done , namely ROUND(days_window * exam_cnt / diff_days, 2) avg_exam_cnt.
SELECT uid, days_window, ROUND(days_window * exam_cnt / diff_days, 2) avg_exam_cnt
FROM (
    SELECT uid,
        COUNT(start_time) exam_cnt,
        DATEDIFF(MAX(start_time), MIN(start_time)) + 1 diff_days, 
        MAX(DATEDIFF(next_start_time, start_time)) + 1 days_window
    FROM (
        SELECT uid, exam_id, start_time,
            lead(start_time) over(
                PARTITION BY uid ORDER BY start_time) next_start_time
        FROM exam_record
        WHERE YEAR(start_time)=2021
    ) exam_record_lead
    GROUP BY uid
) exam_record
WHERE diff_days > 1
ORDER BY days_window DESC, avg_exam_cnt DESC;

SQL30 The number of papers that have not been completed in the past three months is 0 User completion of

describe

Existing test paper answer record form exam_record(uid: user ID, exam_id: The examination paper ID, start_time: Start answering time , submit_time: Submission time , If it is blank, it means that it has not been completed , score: score ):

iduidexam_idstart_timesubmit_timescore
1100690032021-09-06 10:01:012021-09-06 10:21:0284
2100690012021-08-02 12:11:012021-08-02 12:31:0189
3100690022021-06-06 10:01:012021-06-06 10:21:0181
4100690022021-05-06 10:01:012021-05-06 10:21:0181
5100690012021-05-01 12:01:01(NULL)(NULL)
6100190012021-09-05 10:31:012021-09-05 10:51:0181
7100190032021-08-01 09:01:012021-08-01 09:51:1178
8100190022021-07-01 09:01:012021-07-01 09:31:0081
9100190022021-07-01 12:01:012021-07-01 12:31:0181
10100190022021-07-01 12:01:01(NULL)(NULL)

problem

Find the number of completed test papers of users who have no test papers in the last three months with test paper answering records , According to the number of completed papers and users ID Descending ranking . The results of the sample data are output as follows :

uidexam_complete_cnt
10063

explain : user 1006 The last three months with test papers are 202109、202108、202106, The number of answer papers is 3, Complete ; user 1001 The last three months with test papers are 202109、202108、202107, The number of answer papers is 5, The number of completed papers is 4, Because there are unfinished papers , So filter it out .

Example

 Input :
drop table if exists exam_record;
CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT ' Self increasing ID',
    uid int NOT NULL COMMENT ' user ID',
    exam_id int NOT NULL COMMENT ' The examination paper ID',
    start_time datetime NOT NULL COMMENT ' Starting time ',
    submit_time datetime COMMENT ' Submission time ',
    score tinyint COMMENT ' score '
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1006, 9003, '2021-09-06 10:01:01', '2021-09-06 10:21:02', 84),
(1006, 9001, '2021-08-02 12:11:01', '2021-08-02 12:31:01', 89),
(1006, 9002, '2021-06-06 10:01:01', '2021-06-06 10:21:01', 81),
(1006, 9002, '2021-05-06 10:01:01', '2021-05-06 10:21:01', 81),
(1006, 9001, '2021-05-01 12:01:01', null, null),
(1001, 9001, '2021-09-05 10:31:01', '2021-09-05 10:51:01', 81),
(1001, 9003, '2021-08-01 09:01:01', '2021-08-01 09:51:11', 78),
(1001, 9002, '2021-07-01 09:01:01', '2021-07-01 09:31:00', 81),
(1001, 9002, '2021-07-01 12:01:01', '2021-07-01 12:31:01', 81),
(1001, 9002, '2021-07-01 12:01:01', null, null);
 Output :
1006|3

answer

Problem disassembly :

  1. First from exam_record Filter users from table ID、 Answer start time 、 score , And in reverse order of the month .
SELECT uid, start_time, score,
           dense_rank() OVER(PARTITION BY uid ORDER BY date_format(start_time, '%Y%m') DESC;
  1. Then , Based on the results filtered in the previous step , Then select the number of questions each person has answered in the past three months , But pay attention to the limitations .
SELECT uid,
       COUNT(score) AS exam_complete_cnt
FROM [ Result set ] WHERE recent_months <= 3;
  1. Finally, according to the number of answers 、 user ID Descending output , The final results are as follows .
SELECT uid,
       COUNT(score) AS exam_complete_cnt
FROM(
    SELECT uid, start_time, score,
           dense_rank() OVER(PARTITION BY uid ORDER BY date_format(start_time, '%Y%m') DESC) 
    AS recent_months
    FROM exam_record
) recent_table
WHERE recent_months <= 3
GROUP BY uid
HAVING COUNT(score) = COUNT(uid)
ORDER BY exam_complete_cnt DESC, uid DESC;
原网站

版权声明
本文为[Cun Yuyao]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206210648271940.html