【SQL】【查询】leetcode 总结

68 阅读3分钟

查询

1. 技巧,多用子查询,先查询出部分数据,不断用in这种方式嵌套子查询语句.

eg.编写解决方案,找出每位学生获得的最高成绩和它所对应的科目,若科目成绩并列,取 course_id 最小的一门。查询结果需按 student_id 增序进行排序。

image.png

思考步骤:

  1. 查询出每位学生获得最高成绩
   select student_id,
           max(grade)
   from Enrollments
   group by student_id
  1. 查询出每位学生获得的最高成绩和它所对应的科目,若科目成绩并列,取 course_id 最小的一门。
    select student_id,
            grade,
            min(course_id)
     from Enrollments
     where 
         (grade,course_id)
         in(
             select student_id,
             max(grade)
             from Enrollments
           )
     group by student_id

3.添加上排序语句

 select student_id,
            min(course_id) as course_id,
            grade
     from Enrollments
     where 
        (student_id,grade)
         in(
             select student_id,
             max(grade)
             from Enrollments
             group by student_id
           )
     group by student_id
     order by student_id

注意:这里的子查询不能是查询 course_id 和 max(grade),为什么呢? 因为结果只会出来一条,所以到底出来的是哪条course_id是未知的,所以这样不可以。总结一下就是:聚合函数永远只会出现对应一条数据,所以一定要查询最distinct的数据作为子查询的数据

2.技巧——是否存在可以用sum语法

eg.报告购买了产品  "A""B"  但没有购买产品  "C"  的客户的 customer_id 和 customer_name,因为我们想推荐他们购买这样的产品。

image.png

  1. 解法1:
    1. 使用子查询,查询customer_id in (买了A) and in (买了B) and not in(买了C)
    select customer_id,
            customer_name
    from Customers
    where cutomer_id in(
            sleect customer_id
            from Orders
            where product_name = 'A'
      ) and cutomer_id in(
            sleect customer_id
            from Orders
            where product_name = 'B'
      ) and cutomer_id NOT in(
            sleect customer_id
            from Orders
            where product_name = 'C'
      )

2.解法2: 1. 使用sum语句来判断有没有相关数据

   select customer_id,
          customer_name
   from Orders o
   left join Customers c using(customer_id)
   group by c.customer_id
   having sum(product_name = 'A') * sum(product_name = 'B') > 0
           and sum(product_name = 'C) = 0

3. 技巧——也不算技巧,就是多使用if substr 这样的函数

eg.编写解决方案,计算每个雇员的奖金。如果一个雇员的 id 是 奇数 并且他的名字不是以 'M' 开头,那么他的奖金是他工资的 100% ,否则奖金为 0 。

image.png

image.png

    select employee_id,
            if(employee_id % 2 = 1 and substr(name,1,1) != 'M',salary,0) as bonus

常用的查询条件语句

日期相关查询条件

//对于日期查询,一般用between...and...  或者是> <相关判断
//查询2020年的订单
where date between '2020-01-01' and '2020-12-31'

聚合函数防止Null出现函数

//为空,则返回0
 coalesce(sum(distance),0)

select的本质是取出数据,可以直接拿过来计算,不同条件给出不同的结果,可以用case语句

select left_operand,
        operator,
        right_operand,
        (
            case
                when e.operator = '>' and v1.value > v2.value then 'true'
                when e.operator = '<' and v1.value < v2.value then 'true'
                when e.operator = '=' and v1.value = v2.value then 'true'
            else
                'false'
            end
        ) as value