leetcode database problem sixth bullet
- 626. Change seats
- 1280. Number of times students took tests in each subject
- 1321. Restaurant Turnover Change Growth
- 1327. List all ordered products within a specified time period
- 1341. Movie Ratings
- 1378. Replace Employee ID with Unique Identifier
- 1393. Capital gains and losses on shares
- 1407. Top Travelers
- 1484. Sell products grouped by date
- 1517. Find users with valid email addresses
- 1527. Patients suffering from certain diseases
- summary
626. Change seats
https://leetcode.cn/problems/exchange-seats/
Well, I looked at this topic again today and found that the use case has been fixed.
# mysql && oracle
select floor((id - 1) / 2) * 2 + row_number() over(partition by floor((id - 1) / 2) order by id desc) id ,student
from seat
# mssql
select (id - 1) / 2 * 2 + row_number() over(partition by (id - 1) / 2 order by id desc) id ,student
from seat
# mssql && mysql
# 这个是抄评论里的内容,可惜不直到怎么调整的能够支持 oracle
select rank() over (order by (id - 1) ^ 1) id, student
from Seat
1280. Number of times students took tests in each subject
https://leetcode.cn/problems/students-and-examinations/
Forehead. . . Count everyone, all subjects, and several assessments have been carried out. . . Then personnel and subjects can only maximize the cross-query, and then associate the number of exams.
In fact, the instructions are one for three, just replace the null value processing with their own functions:
oracle : nvl
mysql : ifnull
mssql : isnull
# oracle
select a.*,nvl(cnt,0) attended_exams
from (
select * from students,subjects
) a
left join (
select student_id,subject_name,count(0) cnt
from examinations
group by student_id,subject_name
) b on a.student_id=b.student_id and a.subject_name=b.subject_name
order by a.student_id,a.subject_name
CSDN illiterate old Gu's blog , https://blog.csdn.net/superwfei
1321. Restaurant Turnover Change Growth
https://leetcode.cn/problems/restaurant-growth/
Forehead. . . . Correlating according to the date, you have to limit the date range of the output, which is not difficult, but it is cumbersome to write, which is close to the appearance of daily work.
The main thing is the usage of datediff in mysql and mssql, the difference is not small, you need to carefully check their grammar and difference calculation method, which date is in front and which date is in the back.
# mysql
select a.visited_on,sum(c.amount) amount,round(sum(c.amount) / 7,2) average_amount
from (
select distinct visited_on
from customer c
where exists(
select 1
from customer
where datediff(c.visited_on,visited_on)=6
)
) a
inner join customer c on datediff(a.visited_on,c.visited_on)<=6 and datediff(a.visited_on,c.visited_on) >= 0
group by a.visited_on
order by a.visited_on
# mssql
select a.visited_on,sum(c.amount) amount,convert(decimal(16,2),sum(c.amount) * 1.0 / 7) average_amount
from (
select distinct visited_on
from customer c
where exists(
select 1
from customer
where datediff(d,visited_on,c.visited_on)=6
)
) a
inner join customer c on datediff(d,c.visited_on,a.visited_on)<=6 and datediff(d,c.visited_on,a.visited_on) >= 0
group by a.visited_on
order by a.visited_on
# oracle
select to_char(a.visited_on,'YYYY-mm-DD') visited_on,sum(c.amount) amount,round(sum(c.amount) * 1.0 / 7,2) average_amount
from (
select distinct visited_on
from customer c
where exists(
select 1
from customer
where c.visited_on - visited_on = 6
)
) a
inner join customer c on c.visited_on between a.visited_on - 6 and a.visited_on
group by a.visited_on
order by a.visited_on
1327. List all ordered products within a specified time period
https://leetcode.cn/problems/list-the-products-ordered-in-a-period/
Well, the date range can be described with between, so that one can drag three. As for the sales volume of not less than 100, just use having aggregation to filter it.
select p.product_name,sum(o.unit) unit
from products p
inner join orders o on p.product_id=o.product_id
where o.order_date between '2020-2-1' and '2020-2-29'
group by p.product_name
having(sum(o.unit)>=100)
1341. Movie Ratings
https://leetcode.cn/problems/movie-rating/
Forehead. Completely two different query conditions, aggregation methods, and then get two result sets, put them together for output. . . The content of this test is not universal. . . . Forget it, just write whatever you want.
Well, the following content is not that a certain data can only use this method, but that different data are implemented in different ways, and friends can also use any database to achieve query results in a specific way .
# mysql
select *
from (
select name results
from movierating m
inner join users u on m.user_id=u.user_id
group by name
order by count(0) desc,name
limit 0,1
) a
union all
select *
from (
select title results
from movierating r
inner join movies m on r.movie_id=m.movie_id
where created_at between '2020-2-1' and '2020-2-29'
group by title
order by avg(rating) desc,title
limit 0,1
) b
# oracle
select *
from (
select u.name results
from movierating m
inner join users u on m.user_id=u.user_id
group by name
order by count(0) desc,name
) a
where rownum=1
union all
select *
from (
select m.title results
from movierating r
inner join movies m on r.movie_id=m.movie_id
where r.created_at between '2020-2-1' and '2020-2-29'
group by title
order by avg(r.rating) desc,title
) b
where rownum=1
# 一拖三,除了 mssql, * 1.0 都可以省略
select a.name results
from (
select a.*,row_number() over(partition by tp order by cnt desc,name) nid
from (
select u.name,sum(1) over(partition by u.user_id order by r.created_at) cnt,'1' tp
from users u
inner join MovieRating r on u.user_id=r.user_id
union all
select m.title,avg(rating * 1.0),'2' tp
from Movies m
inner join MovieRating r on m.movie_id=r.movie_id
where created_at >= '2020-2-1' and created_at < '2020-3-1'
group by title
) a
) a
where a.nid=1
1378. Replace Employee ID with Unique Identifier
https://leetcode.cn/problems/replace-employee-id-with-the-unique-identifier/
Ah, I went back to the left join test again, and I have no other ideas at all.
select u.unique_id,e.name
from Employees e
left join EmployeeUNI u on e.id=u.id
1393. Capital gains and losses on shares
https://leetcode.cn/problems/capital-gainloss/
Um? This question is actually rated as medium difficulty? I didn't see it, isn't it still a problem with group and sum? Oh, is a case when considered a difficulty?
# 一拖三
select a.stock_name,sum(p) capital_gain_loss
from (
select s.*,(case when operation = 'Buy' then -price else price end) p
from stocks s
) a
group by a.stock_name
1407. Top Travelers
https://leetcode.cn/problems/top-travellers/submissions/
Forehead. . . Or left join an aggregation result. . .
# oracle
select a.name,nvl(b.d,0) as travelled_distance
from users a
left join (
select user_id,sum(distance) d
from rides
group by user_id
) b on a.id=b.user_id
order by nvl(b.d,0) desc,a.name
# mssql
select name,isnull(d,0) travelled_distance
from users a
left join (
select user_id,sum(distance) d
from rides
group by user_id
) b on a.id=b.user_id
order by d desc,name
# mysql
select name,ifnull(sum(distance),0) travelled_distance
from users a
left join rides r on r.user_id=a.id
group by a.id
order by travelled_distance desc,name
1484. Sell products grouped by date
https://leetcode.cn/problems/group-sold-products-by-the-date/
Oh, I finally used group_concat or for xml. Unfortunately, Lao Gu is not familiar with oracle, so I don’t know how to get this result in oracle.
# mysql
select sell_date,count(distinct product) num_sold,group_concat(distinct product order by product) products
from Activities
group by sell_date
order by sell_date
# mssql
select distinct sell_date,len(products) - len(replace(products,',','')) + 1 num_sold,products
from Activities a
cross apply (
select stuff((
select distinct ',' + product
from Activities
where sell_date=a.sell_date
order by ',' + product
for xml path('')
),1,1,'') products
) b
order by sell_date
1517. Find users with valid email addresses
https://leetcode.cn/problems/find-users-with-valid-e-mails/
Forehead. . . . This topic is easy with official regular support, but mssql does not have official regular support. . . You can only test strings. . . . Fortunately, tsql's like also has a similar regular usage, although it is not a complete regular.
# mysql
select *
from Users
where mail regexp '^[a-zA-Z][a-zA-Z0-9_\.-]*@leetcode[\.]com$'
# oracle
select *
from Users
where regexp_like(mail,'^[a-zA-Z][a-zA-Z0-9_\.-]*@leetcode[\.]com$')
# mssql
select *
from users
where mail like '[a-zA-Z]%@leetcode.com'
and substring(mail,0,len(mail) - 12) not like '%[^a-zA-Z0-9_.-]%'
1527. Patients suffering from certain diseases
https://leetcode.cn/problems/patients-with-a-condition/
Uh-huh. For this topic, regex is still easier to use than like, especially when like needs or, the efficiency is too low.
# mssql
select *
from patients
where ',' + replace(conditions,' ',',') like '%,diab1%'
# mysql
select *
from Patients
where conditions regexp '(?<![a-z0-9A-Z])DIAB1'
# oracle
select *
from Patients
where regexp_like(conditions,'(^| )DIAB1')
summary
Well, the 10 questions this time are quite comprehensive, especially the combination of grouped strings, which is a very common content, and then, regularization, which is also a very common content.
However, in the absence of regularization, we still have a way to change the content of the determined string. Well, this time there are two questions that use like to work around to get the correct result.
Therefore, we must understand clearly what functions each command has and what operations it can perform.
All gorgeous moves are composed of basic movements. Only by understanding all the basic content can you complete all requirements without any tricks.