Leetcode SQL membership questions [Summary of vomiting blood~~] Day 4

Table of contents

1173. Instant Food Delivery I
1174. Instant Food Delivery II
1193. Monthly Transactions I
1194. Championship Winner
1204. Last person to enter the elevator
1205. Monthly Transactions II
1211. Quality and proportion of query results
1212. Query Team points
1225. Consecutive dates for reporting system status
1241. Comments per post
1251. Average sale price
1264. Page recommendations
1270. All people reporting to the CEO of the company
1280. Number of tests students took in each subject
1285. Find the starting and ending numbers of a continuous interval

1173. Instant food delivery I

Insert image description here

  • source code:
    select round(sum(case when order_date = customer_pref_delivery_date then 1 else 0 end) / count(delivery_id) * 100, 2) as immediate_percentage
    from delivery
    
  • Idea: sum() + case whenUsing this method simplifies this question a lot. This is also an experience.

1174. Instant Food Delivery II

Insert image description here

  • source code:
    with first_order as (
        select delivery_id
        from delivery
        where (customer_id, order_date) in (
            select customer_id, min(order_date)
            from delivery
            group by customer_id
        )
    )
    select 
        round(
            sum(case when order_date=customer_pref_delivery_date and delivery_id in (select * from first_order) then 1 else 0 end)
            / (select count(*) from first_order) * 100
        , 2) as immediate_percentage
    from delivery
    
  • Idea: It is important to understand the demand. This question is to ask for the proportion of immediate orders among first-time orders. Therefore, we can first find out which first-time orders there are, and then use subqueries to determine the number of orders that are both immediate orders and first-time orders.

1193. Monthly Transactions I

Insert image description here

  • source code:
    select
        left(trans_date, 7) as month, country,
        count(id) as trans_count, 
        count(case when state = 'approved' then 1 else null end) as approved_count,
        sum(amount) as trans_total_amount,
        sum(case when state = 'approved' then amount else 0 end) as approved_total_amount
    from transactions
    group by left(trans_date, 7), country
    
  • Idea: First we need to know how to get the date in front of the string. There are two ways substr() / left(); then figure out the grouping field and then perform aggregation.

1194. Tournament Winner

Insert image description here

  • source code:
    select group_id, id player_id
    from (
        select group_id, id, row_number() over(partition by group_id order by total_score desc, id) rk
        from (
            select id, sum(score) total_score
            from (
                select match_id, first_player id, first_score score
                from matches
                union all
                select match_id, second_player id, second_score score
                from matches
            ) t
            group by id
        ) t
        join players
        on t.id = players.player_id
    ) t
    where rk = 1
    
  • Idea: According to the need to accumulate the scores of the players as mentioned in the question, that is, whether they are the first player or the second player, they need to be accumulated, so we can split one table into two tables sum. In this way, we can find the cumulative score of each player, and then find the player with the highest score in the group.

1204. The last person to enter the elevator

Insert image description here

  • source code:
    select person_name
    from (
        select person_name, sum(weight) over(order by turn) sum_weight
        from queue
    ) t
    where sum_weight <= 1000
    order by sum_weight desc
    limit 1;
    
  • Idea: By sumopening the window on the function, you can get the cumulative weight sum. As long as you take out the person who is less than or equal to 1000 and the largest, he will be the last person who has the right weight and enters the elevator.

1205. Monthly Transactions II **

Insert image description here

  • source code:
    with base as (
        select 'approved' tag, country, substr(trans_date, 1, 7) month, amount
        from Transactions where state = 'approved'
        union all
        select 'chargeback' tag, t.country, substr(cb.trans_date, 1, 7) month, t.amount
        from Chargebacks cb join Transactions t on cb.trans_id = t.id
    )
    select month, country, 
           sum(if(tag = 'approved', 1, 0)) approved_count,
           sum(if(tag = 'approved', amount, 0)) approved_amount,
           sum(if(tag = 'chargeback', 1, 0)) chargeback_count,
           sum(if(tag = 'chargeback', amount, 0)) chargeback_amount
    from base 
    group by month, country;
    
  • Idea: First label the data, and then union allperform grouping and aggregation;
  • Focus on learning the idea of ​​​​this question. I remember asking for the maximum number of continuous online people in the live broadcast room. This is also the idea.

1211. Quality and proportion of query results

Insert image description here

  • source code:
    select 
        query_name, 
        round(avg(rating / position), 2) quality, 
        round(sum(case when rating < 3 then 1 else 0 end) / count(*) * 100, 2) poor_query_percentage 
    from queries
    group by query_name
    
  • Idea: The requirements are relatively simple, and there is no logic that is particularly difficult to understand.

1212. Query team points

Insert image description here

  • source code:
    select team_id, team_name, ifnull(score, 0) as num_points 
    from teams 
    left join (
        select id, sum(score) score
        from (
            -- 作为主场
            select  
                host_team id, 
                sum(case when host_goals > guest_goals then 3 when host_goals = guest_goals then 1 else 0 end) score
            from matches
            group by id
            union all 
            -- 作为客场
            select  
                guest_team id, 
                sum(case when host_goals < guest_goals then 3 when host_goals = guest_goals then 1 else 0 end) score
            from matches
            group by id
        ) t
        group by id
    ) t
    on teams.team_id = t.id
    order by num_points desc, team_id;
    
  • Idea: The core logic is left jointhe logic on the right. We first calculate the home score, then calculate the away score, and finally add these two parts together.

1225. Report system status on consecutive dates **

Insert image description here

  • source code:
    select type period_state , min(dt) start_date, max(dt) end_date
    from 
    (
        select  
            type, dt,
            subdate(dt, row_number() over(partition by type order by dt)) diff
        from (
            select 'succeeded' type, success_date dt
            from succeeded
            where success_date between '2019-01-01' and '2019-12-31'
            union 
            select 'failed' type, fail_date dt
            from failed
            where fail_date between '2019-01-01' and '2019-12-31'
        ) t
    ) t
    group by type, diff
    order by start_date;
    
  • Idea: 类似于求最大连续登陆天数问题, the difference is that this question asks for the start and end time of continuous login! This question requires connecting two tables, and then you need to create a field yourself (a very good idea ), and then apply the maximum continuous login problem routine date_sub + row_numberto solve it.

1241. Number of comments per post

Insert image description here

  • source code:
    select sub_id post_id, ifnull(number_of_comments, 0) number_of_comments
    from (
        select distinct sub_id
        from submissions
        where parent_id is null
    ) t1
    left join (
        select parent_id, count(distinct sub_id) number_of_comments 
        from submissions
        where parent_id is not null
        group by parent_id
    ) t2
    on t1.sub_id = t2.parent_id
    order by post_id;
    
  • Idea: Just make it clear whether each piece of data is a post or a comment; then pay attention to removing duplicates!

1251. Average selling price

Insert image description here

  • source code:
    select 
        product_id, 
        round(sum(price * units) / sum(units), 2) average_price
    from 
    (
        select p.product_id, price, units 
        from prices p 
        join unitssold u 
        on p.product_id = u.product_id and purchase_date between start_date and end_date
    ) t
    group by product_id;
    
  • Idea: relatively simple

1264. Page recommendation

Insert image description here

  • source code:
    select distinct page_id as recommended_page
    from (
        select page_id 
        from likes
        where user_id in (
            select case when user1_id = 1 then user2_id else user1_id end 
            from friendship 
            where user1_id = 1 or user2_id = 1
        ) 
    ) t
    where page_id not in (
        select page_id
        from likes
        where user_id = 1
    )
    ;
    
  • Idea: It’s relatively simple, you just need to pay attention to some of the details.

1270. Everyone who reports to the CEO of the company *

Insert image description here

  • source code:
    select 
       e3.employee_id
    from employees e1, employees e2, employees e3 
    where 
       -- 根据题目说的要找出所有经理为1的员工id
       e1.manager_id  = 1 and 
       -- 根据上面一个条件找出直接经理为1的员工id,然后让这些员工id作为第二张表的经理,来获取所有的员工id
       e2.manager_id = e1.employee_id and  
       -- 根绝上面一个条件找出直接或者间接一次得到的所有员工id,然后让这些员工id作为第三张表的经理,来获取所有的员工id
       e3.manager_id = e2.employee_id and 
       -- 排除自己的经理就是自己的员工id
       e3.employee_id != 1
    ;
    
  • Idea: It is easy to get the answer to this question without writing a program, but it is more difficult to implement it through a program. I have explained the wheremeaning of each sentence in the above source code.

1280. Number of tests students took in each subject

Insert image description here

  • source code:
    select t1.student_id, student_name, t1.subject_name, count(ex.student_id) attended_exams
    from (
       select student_id, student_name, subject_name
       from students
       join subjects
       on 1 = 1
    ) t1
    left join examinations ex
    on t1.student_id = ex.student_id and t1.subject_name = ex.subject_name
    group by t1.student_id, t1.subject_name
    order by t1.student_id, t1.subject_name;
    
  • Idea: It involves a Cartesian product connection , which can be usedcross join

1285. Find the starting and ending numbers of a continuous interval

Insert image description here

  • source code:
    select 
       min(log_id) start_id,
       max(log_id) end_id
    from (
       select log_id, (log_id - row_number() over(order by log_id)) diff
       from logs
    ) t
    group by diff
    order by start_id
    
  • Idea: Exactly the same as the above question, find the maximum and minimum time for continuous login

Guess you like

Origin blog.csdn.net/qq_42397330/article/details/124082376