Interview handwritten SQL - ask for the names of students who have passed 3 consecutive days?

Interview Handwritten SQL - Asking several questions for 3 consecutive days, I finally got it!

Some time ago, when Xiaoming went to a company in Shanghai for an interview, he was confused. The interviewer directly asked him to write SQL on the spot. He was also confused at the time when he asked the question. It is not easy to think of in that kind of tense atmosphere, so Xiao Ming made up his homework after class!

Interview question: Write the names of students who scored 60 or higher for three consecutive days?

problem analysis:

The key point of this topic is how to express the three consecutive days. It is necessary to change the thinking here, otherwise it will be difficult to do it. In the end, it is still a bit less written in SQL. Looking at the problem, three consecutive days means consecutive dates. If we give you a table, we will quickly find out the consecutive qualified students. The reason is that our brains are very familiar with the table, but if you write it out with a program , you will find that the thinking suddenly freezes, so the key point is to program the thinking of reading data from the table. Give you a table, you will first locate the row where the student passed the first grade according to a certain student, and then find out whether the student's grade is qualified according to the next day of the date of the current row. If qualified, then continue to go. Let's see if the next day is qualified. If there are three consecutive days, then we will get the result we want. Well, our thinking is like this, and our program should be like this, so let's program our thinking. , the key point is how to judge whether there is a next day in SQL, yes, you have thought, exists, this powerful function of SQL can help us achieve, let's run the code!

1. Build a table

create table student (
       id varchar2(20) primary key,
       name varchar2(20),
       rq date,
       score number(10)
       )

2. Insert experimental data

insert into student values('1','菜鸟1号',to_date('2021-11-01','YYYY-MM-DD'),60);
insert into student values('2','菜鸟1号',to_date('2021-11-02','yyyy-mm-DD'),67);
insert into student values('3','菜鸟1号',to_date('2021-11-03','YYYY-MM-DD'),90);
insert into student values('13','菜鸟1号',to_date('2021-11-04','YYYY-MM-DD'),90);
insert into student values('4','菜鸟2号',to_date('2021-11-01','YYYY-MM-DD'),50);
insert into student values('5','菜鸟2号',to_date('2021-11-02','YYYY-MM-DD'),60);
insert into student values('6','菜鸟2号',to_date('2021-11-03','YYYY-MM-DD'),70);
insert into student values('7','菜鸟3号',to_date('2021-11-01','YYYY-MM-DD'),50);
insert into student values('8','菜鸟3号',to_date('2021-11-02','YYYY-MM-DD'),45);
insert into student values('9','菜鸟3号',to_date('2021-11-03','YYYY-MM-DD'),90);
insert into student values('10','菜鸟4号',to_date('2021-11-01','YYYY-MM-DD'),100);
insert into student values('11','菜鸟4号',to_date('2021-11-02','YYYY-MM-DD'),100);
insert into student values('12','菜鸟4号',to_date('2021-11-03','YYYY-MM-DD'),100);

3. Get the table we want to query
insert image description here4. SQL implementation

select distinct name from student t1 where 
exists (select 1 from student t2 where t2.rq = t1.rq+1 and t2.name = t1.name 
and 
exists (select 1 from student t3 where t3.rq= t2.rq+1 and t3.name = t2.name)) and score >=60

Distinct is used because when SQL is performing a date judgment search, it will check whether there are consecutive days from each date, because rookie No. 1 is qualified for four consecutive days. If distinct is not added above, there will be two rookies. No. 1, we only need to find out the qualified students, so we have to recheck it.

5. Execution results

insert image description here
After it is written, it is very simple, but this is not what we want. Imagine if it is very slow to judge every date, so we have to optimize, this is what we must consider, so the point is here! ! !

Let's introduce a very important and very useful function row_number() over() in SQL, window function, with this function, you can sort the data in the group, let's optimize and rewrite the above SQL, Here is a little trick for continuous processing of dates, which is to subtract each sort number from the date, which is exactly the same value. It is easy to remember this .

row_number() over()

Syntax format: row_number() over(partition by grouping column order by sorting column desc)

Partition by is to group fields. Like group by, some fields can be grouped, but unlike order by after group by, order by can be used after partition by to sort within the group, and then use row_number() Returns the sort number.

For more usage of the OVER windowing function, please refer to an article: https://blog.51cto.com/u_15057820/2650448 After reading it, I suddenly realized.

1. Group the students and sort by date within the group

select s.*,row_number() over(partition by name order by rq) rn from student s where score >=60

insert image description here
2. Screen out consecutive eligible students on dates ( critical )

select name, count(1) as day from
(
select s.*,row_number() over(partition by name order by rq) rn from student s where score >=60
) t
group by name,rq-rn

insert image description here
3. Filter data for three consecutive days

select name, count(1) as day from
(
select s.*,row_number() over(partition by name order by rq) rn from student s where score >=60
) t
group by name,rq-rn  having count(1) >=3

insert image description here
You're done! We got the result we wanted and mastered how to represent consecutive dates, so when we encounter various similar problems, for example, we need to log in users for 3 consecutive days, calculate the transaction amount for 3 consecutive days, etc., we will no longer be confused! If friends have a more convenient and efficient method, please leave a message, and we can learn together.

Guess you like

Origin blog.csdn.net/qq_38338409/article/details/121582966