Advertisement

leetcode-sql-刷题汇总(补充ing)

阅读量:

文章目录

  • leetcode-sql-刷题汇总
    • 607. 销售员

    • 197. 上升的温度

    • 1148. 文章浏览 I

    • 1581. 进店却未进行过交易的顾客

    • 608. 树节点

    • 1795. 每个产品在不同商店的价格(列转行)

    • 1965. 丢失信息的雇员

    • 1527. 患某种疾病的患者

    • 1484. 按日期分组销售产品

    • 1667. 修复表中的名字(首字母转大写)

    • 185. 部门工资前三高的所有员工

    • 184. 部门工资最高的员工

    • 182. 查找重复的电子邮箱

    • 181. 超过经理收入的员工

    • 196. 删除重复的电子邮箱(保留id最小的)

    • 627. 变更性别

      • 思路1: 使用ascii码
      • 思路2: if判断
      • 思路3: case when
    • 1873. 计算特殊奖金

    • 180. 连续出现的数字

      • 思路1: 分组,把连续出现的相同数组分成一组,然后统计这组的个数,大于3则符合要求筛选出来
      • 思路2: 如果要求是3次,那么其实不用分组:只需要知道:某一行,改行前的num和当前相同,该行后num和当前相同,该num则符合要求
    • 178. 分数排名

      • 思路1: dense_rank
    • 177. 第N高的薪水

      • 思路1: row_number
      • 思路2: limit offset
      • 思路3: 严谨点IFNULL
      • 思路4: group去重
    • 176. 第二高的薪水

        • 思路1: row_number
    • 思路2:limit offset

    • 思路3: 和思路2相同,只不过加了ifnull

    • 175. 组合两个表

leetcode-sql-刷题汇总

607. 销售员

https://leetcode-cn.com/problems/sales-person/

复制代码
    # 思路1: not in 
    select name 
    from 
    SalesPerson
    where name not in 
    (select s.name
    from 
    Company as c
    join 
    Orders as o 
    on c.com_id = o.com_id
    join 
    SalesPerson as s 
    on o.sales_id = s.sales_id
    where c.name = 'RED')
    
    
    # 思路2: 不需要找到人名,只需要找到id,排除id即可
    select
    name
    from
    salesperson
    where
    sales_id not in 
    (select sales_id from orders where com_id in 
        (select com_id from company where name = 'RED'))

197. 上升的温度

https://leetcode-cn.com/problems/rising-temperature/

复制代码
    # Write your MySQL query statement below
    
    # 这个不对,因为数据可能不是日期连续的。。。
    select id 
    from 
    (select 
    id, 
    lag(Temperature, 1) over (order by recordDate) as preTemperature, Temperature,
    lag(recordDate, 1) over (order by recordDate) as preRecordDate, recordDate
    from
    Weather)as t 
    where 1 
    and DATE_ADD(preRecordDate, interval 1 day) = recordDate
    and Temperature > preTemperature 
    
    
    
    
    # 思路2:就是笛卡尔积,然后判断出来即可
    select t2.id 
    from 
    Weather as t1 
    join 
    Weather as t2 
    where 1
    and DATE_ADD(t1.recordDate, interval 1 day) = t2.recordDate
    and t2.Temperature > t1.Temperature

1148. 文章浏览 I

https://leetcode-cn.com/problems/article-views-i/

复制代码
    # 思路1: 就where即可
    select distinct author_id as id
    from Views 
    where author_id = viewer_id
    order by author_id

1581. 进店却未进行过交易的顾客

https://leetcode-cn.com/problems/customer-who-visited-but-did-not-make-any-transactions/

复制代码
    # 思路1: left join 
    select v.customer_id, 
    count(1) as count_no_trans
    from 
    Visits as v 
    left join 
    Transactions as t 
    on v.visit_id = t.visit_id
    where t.transaction_id is null
    group by v.customer_id

608. 树节点

https://leetcode-cn.com/problems/tree-node/

复制代码
    # 思路1: 就关联出父节点和子节点即可
    select id, 
    if(p_count > 0 && c_count > 0, 'Inner', if(p_count = 0, 'Root', 'Leaf')) as type
    from 
    (select t1.id, 
    # t2.id as p_id, t3.id as child_id,
    count(t2.id) as p_count,
    count(t3.id) as c_count
    from 
    tree as t1 
    left join 
    tree as t2 
    on t1.p_id = t2.id
    left join 
    tree as t3 
    on t3.p_id = t1.id
    group by id) as tt

1795. 每个产品在不同商店的价格(列转行)

https://leetcode-cn.com/problems/rearrange-products-table/

复制代码
    # Write your MySQL query statement below
    
    # 思路1: 常规列转行
    #用union all是因为它不去重,这里去不去重都不影响结果,所以选个更少运算的
    select product_id, 'store1' as store, store1 as price
    from products
    where store1 is not null
    union all 
    select product_id, 'store2' as store, store2 as price
    from products
    where store2 is not null
    union all
    select product_id, 'store3' as store, store3 as price
    from products
    where store3 is not null;
    
    
    # 思路2: mysql 不太好用
    # select product_id,lower(store) as store,price
    # from Products
    # unpivot (price for store in (store1, store2, store3))

1965. 丢失信息的雇员

https://leetcode-cn.com/problems/employees-with-missing-information/

复制代码
    # 思路1: 常规思路
    select employee_id from employees
    where employee_id not in (select employee_id from salaries)
    union
    select employee_id from salaries
    where employee_id not in (select employee_id from employees)
    order by employee_id
    
    # 思路1: 常规思路
    SELECT A.employee_id
    FROM employees A LEFT JOIN salaries B ON A.employee_id = B.employee_id
    WHERE B.salary IS NULL
    UNION
    SELECT A.employee_id
    FROM salaries A LEFT JOIN employees B ON A.employee_id = B.employee_id
    WHERE B.name IS NULL
    order by employee_id
    
    # 思路2
    with tmp as(
    select employee_id from employees 
    union all
    select employee_id from salaries
    )
    select
    employee_id
    from tmp t group by employee_id having count(1)=1 order by employee_id

1527. 患某种疾病的患者

https://leetcode-cn.com/problems/patients-with-a-condition/

复制代码
    # 思路1:这也可以没啥问题
    select * from Patients 
    where conditions like 'DIAB1%' or conditions like '% DIAB1%'
    
    # 思路2:正则匹配
    select 
    patient_id,patient_name,conditions
    from
    Patients
    where conditions REGEXP '^DIAB1| +DIAB1'

1484. 按日期分组销售产品

https://leetcode-cn.com/problems/group-sold-products-by-the-date/

复制代码
    select 
    sell_date, 
    count(distinct product) as num_sold,
    group_concat(distinct product order by product) as products
    from 
    Activities
    group by sell_date

1667. 修复表中的名字(首字母转大写)

https://leetcode-cn.com/problems/fix-names-in-a-table/

复制代码
    select user_id, 
    concat(upper(SUBSTRING(name,1,1)), lower(SUBSTRING(name,2,length(name)))) as name
    from
    Users
    order by user_id

185. 部门工资前三高的所有员工

https://leetcode-cn.com/problems/department-top-three-salaries/

复制代码
    # 思路1:还是dense_rank的使用
    select Department, Employee, Salary
    from 
    (select d.name as Department, e.name as Employee,  e.salary as Salary,
    dense_rank() over (partition by d.id order by salary desc) as dense_rk
    from 
    Employee as e 
    join 
    Department as d 
    on e.departmentId = d.id) as t
    where dense_rk <= 3;

184. 部门工资最高的员工

https://leetcode-cn.com/problems/department-highest-salary/

复制代码
    # 思路1: dense_rank()
    select Department, name as Employee, salary
    from 
    (select d.name as Department, 
    e.name, e.salary,
    dense_rank() over (partition by d.name order by salary desc) as rn
    from 
    Employee as e 
    join 
    Department as d 
    on e.departmentId = d.id) as t 
    where t.rn = 1;
    
    # 思路2: 原来可以这样的啊
    select 
    d.Name as Department,
    e.Name as Employee,
    e.Salary 
    from 
    Employee e, Department d 
    where
    e.DepartmentId=d.id 
    and
    (e.Salary,e.DepartmentId) in 
    (select max(Salary),DepartmentId from Employee group by DepartmentId);
    
    
    # 求出最大工资,然后关联
    select t3.name department, t2.name Employee, salary
    from (
    select departmentid, max(salary) max_salary
    from Employee
    group by departmentid
    ) t1
    join Employee t2
    on t1.departmentid = t2.departmentid and t1.max_salary = t2.salary
    join department t3
    on t1.departmentid = t3.id

182. 查找重复的电子邮箱

https://leetcode-cn.com/problems/duplicate-emails/

复制代码
    # 思路1
    select Email
    from Person
    group by Email
    having count(1) > 1

181. 超过经理收入的员工

https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/

复制代码
    # 这里其实直接join也可以
    select emp.name as Employee
    from 
    Employee as emp
    left join 
    Employee as man
    on emp.managerId = man.id 
    where emp.salary > man.salary

196. 删除重复的电子邮箱(保留id最小的)

https://leetcode-cn.com/problems/delete-duplicate-emails/

复制代码
    # 思路1: 直接找到最小id,删除掉not in的数据即可
    delete from Person where id not in
    (select id from 
    (select min(id) as id
    from Person
    group by email) as t)

627. 变更性别

https://leetcode-cn.com/problems/swap-salary/

思路1: 使用ascii码

思路2: if判断

思路3: case when

复制代码
    # 思路1: 使用ascii码
    # update Salary set sex = char(211-ascii(sex));
    # update salary set sex = char(ascii('m') + ascii('f') - ascii(sex));
    
    # 思路2: if判断
    # update salary set sex=if(sex="m","f","m");
    
    # 思路3: case when
    update salary set sex = (case sex when 'm' then 'f' else 'm' end);

1873. 计算特殊奖金

https://leetcode-cn.com/problems/calculate-special-bonus/

复制代码
    select employee_id, 
    if(employee_id%2!=0 && name not like 'M%', salary, 0) as bonus
    from Employees
    order by employee_id

180. 连续出现的数字

https://leetcode-cn.com/problems/consecutive-numbers/

思路1: 分组,把连续出现的相同数组分成一组,然后统计这组的个数,大于3则符合要求筛选出来

复制代码
    # 思路1: 分组,把连续出现的相同数组分成一组,然后统计这组的个数,大于3则符合要求筛选出来
    select distinct num as ConsecutiveNums
    from
    (select num, group_id, 
    count(1) as show_times
    from
    (select id, num, lag_num,
    sum(if(lag_num = null or lag_num = num, 0, 1)) over (order by id) as group_id
    from (
    select id, 
    num,
    lag(num, 1) over (order by id) as lag_num
    from `Logs`
    ) as t1 ) as t2
    group by num, group_id) as t3
    where show_times >= 3

思路2: 如果要求是3次,那么其实不用分组:只需要知道:某一行,改行前的num和当前相同,该行后num和当前相同,该num则符合要求

复制代码
    select distinct num as ConsecutiveNums 
    from(
    select id, num,
      lead(Num) over (order by Id) as nxt_num,
    lag(Num) over(order by Id) as lst_num
    FROM Logs)t
    where nxt_num=num and lst_num=num

178. 分数排名

https://leetcode-cn.com/problems/rank-scores/

思路1: dense_rank

复制代码
    # 思路1:
    # 难道是没有这个函数吗
    # 艹,rank是关键字。。。
    select score, 
    dense_rank() over (order by score desc) as `rank`
    from Scores;
    
    # select
    #     score,
    #     (dense_rank() over (order by Score desc)) AS "rank" 
    # from
    #     Scores

177. 第N高的薪水

https://leetcode-cn.com/problems/nth-highest-salary/

思路1: row_number

复制代码
    CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
    BEGIN
      RETURN (
        # 思路1
        select (select salary 
        from 
        (select salary, row_number() over (order by salary desc) as rn
        from (
        select DISTINCT salary from Employee) as r
        ) as t 
        where rn = N ) as SecondHighestSalary
      );
    END

思路2: limit offset

复制代码
    CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
    BEGIN
    SET N := N-1;
      RETURN (
        # 思路2
        # 注意:SET N := N-1;
        select (select DISTINCT salary
        from Employee
        order by salary DESC
        limit 1 offset N) as SecondHighestSalary
      );
    END

思路3: 严谨点IFNULL

复制代码
    CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
    BEGIN
    SET N := N-1;
      RETURN (
        # 思路3
        # 注意:SET N := N-1;
        select IFNULL((select DISTINCT salary
        from Employee
        order by salary DESC
        limit 1 offset N),NULL) as SecondHighestSalary
      );
    END

思路4: group去重

复制代码
    CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
    BEGIN
    SET N := N-1;
      RETURN (
        # 思路4:
        # 注意:SET N := N-1;
        SELECT 
                salary
        FROM 
                employee
        GROUP BY 
                salary
        ORDER BY 
                salary DESC
        LIMIT N, 1
      );
    END

176. 第二高的薪水

https://leetcode-cn.com/problems/second-highest-salary/

思路1: row_number

从某张表获取,如果没有数据,结果就没没有了
如果是自查询,没有数据的时候会返回null

复制代码
    select (select salary 
    from 
    (select salary, row_number() over (order by salary desc) as rn
    from (
    select DISTINCT salary from Employee) as r
    ) as t 
    where rn = 2 ) as SecondHighestSalary
思路2:limit offset
复制代码
    select (select DISTINCT salary
    from Employee
    order by salary DESC
    limit 1 offset 1) as SecondHighestSalary;
思路3: 和思路2相同,只不过加了ifnull
复制代码
    select IFNULL((select DISTINCT salary
    from Employee
    order by salary DESC
    limit 1 offset 1),NULL) as SecondHighestSalary;

175. 组合两个表

https://leetcode-cn.com/problems/combine-two-tables/

复制代码
    select firstName, lastName, 
    city, state    
    from 
    Person as p 
    left join 
    Address as a 
    on p.PersonId = a.PersonId

全部评论 (0)

还没有任何评论哟~