美文网首页
LeetCode 数据库笔记

LeetCode 数据库笔记

作者: 堂堂正正的大号 | 来源:发表于2020-07-08 20:38 被阅读0次

    SQL子查询:在一个表表达中可以调用另一个表表达式,这个被调用的表表达式叫做子查询(subquery)

    • 子查询必须放在小括号中
    • 子查询一般放在比较操作符的右边,以增强代码可读性
    • 子查询(小括号里的内容)可出现在几乎所有的SELECT子句中(如:SELECT子句、FROM子句、WHERE子句、ORDER BY子句、HAVING子句……)

    子查询分类:

    1. 按方式分类: 嵌套子查询相关子查询
      嵌套子查询的执行不依赖与外部的查询,而相关查询则依赖

    嵌套子查询示例:(查询Book表中价格小所有于图书平均价格的图书的信息)

    SELECT *  
    FROM   Books  
    WHERE  价格 < ( SELECT  AVG(价格)   FROM   Books );
    

    相关子查询示例:(查询Book表中大于该类图书价格平均值的图书信息)

    SELECT*  
    FROM   Books  AS a 
    WHERE  价格 > (
                    SELECT  AVG(价格)   
                    FROM   Books );
    

    相关子查询执行过程:
    (1)从外层查询中取出一个元组,将元组相关列的值传给内层查询。
    (2)执行内层查询,得到子查询操作的值。
    (3)外查询根据子查询返回的结果或结果集得到满足条件的行。
    (4)然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕。

    一般来说,能用子查询解决的问题也能用连接解决

    1. 按返回结果集分类:表子查询行子查询列子查询标量子查询
    • 标量子查询:返回1行1列一个值
    SELECT num,name
    FROM employee
    WHERE d_id=(
                 select d_id
                 from department
                 where d_name='科技部' ) ;
    

    可以指定一个标量表达式的任何地方,几乎都可以使用一个标量子查询,使用 = > < >= <= <> 这些比较标量结果的比较操作符。

    • 行子查询:返回的结果集是 1 行 N 列
    SELECT playerno 
    FROM players 
    WHERE (sex, town) = (
                          select sex, town 
                          from players 
                          where playerno = 100 ) ;
    

    由于行子查询返回的结果集是 一行N列,因此不能直接使用 = > < >= <= <> 这些比较标量结果的比较操作符。
    在行子查询中可以使用 IN、NOT IN等操作符。

    • 列子查询:返回的结果集是 N 行 1列
    SELECT playerno, name, town 
    FROM players 
    WHERE playerno in 
                     ( select playerno 
                       from players 
                       where sex = 'F' ) ;
    

    由于列子查询返回的结果集是 N 行一列,因此不能直接使用 = > < >= <= <> 这些比较标量结果的比较操作符。
    在列子查询中可以使用 IN、ANY、SOME、和ALL等操作符(与比较操作符联合使用)。

    • 表子查询:返回的结果集是 N 行 N 列
    SELECT playerno 
    FROM (
        select playerno, sex 
        from players 
        where playerno < 10  ) AS players10 
    WHERE sex='M' ;
    
    1. 按照对返回结果的调用方法分类,where型子查询from型子查询exists型子查询以及select型子查询
      • where型子查询:(把内层查询结果当作外层查询的比较条件)
        定义:where型的子查询就是把内层查询的结果当作外层查询的条件。
      • from型子查询:(把内层的查询结果供外层再次查询)
        定义:from子查询就是把子查询的结果(内存里的一张表)当作一张临时表,然后再对它进行处理。
      • exists型子查询:(把外层查询结果拿到内层,看内层的查询是否成立)
      • select型子查询:select子查询 (关键点:一个商品id,子查询只能返回一条数据,如果子查询返回多条数据则会出错)

    SQL 中having 和where的区别:where子句用于筛选数据,不能用聚合函数;having子句可使用聚合函数,其专门用于配合group by。

    WHERE:

     SELECT Email 
    FROM(
          select Email , count( Email ) as num
          from Person
          group by Email ) as statistic
    WHERE num > 1
    

    Having:

    SELECT Email 
    FROM  Person
    GROUP BY Email
    Having count( Email ) > 1
    

    SQL中where子句中不能出现聚合函数的原因 (语法问题?)


    Null表示空值(但还是一个值),而查询不到的结果Null表示没有值
    IF函数与IFNULL函数的使用
    Limit的使用

    LeetCode第176题

    方法一:使用子查询和 LIMIT 子句
    将不同的薪资按降序排序,然后使用 LIMIT 子句获得第二高的薪资。

    SELECT DISTINCT Salary AS SecondHighestSalary
    FROM Employee
    ORDER BY Salary DESC
    LIMIT OFFSET 1
    

    然而,如果没有这样的第二最高工资,这个解决方案将被判断为 “错误答案”,因为本表可能只有一项记录。为了克服这个问题,我们可以将其作为临时表(Select Null 返回 Null)

    SELECT ( 
             select distinct Salary 
             from Employee
             order by Salary desc
             limit 1 offset 1 ) AS SecondHighestSalary
    

    方法二:使用函数 IFNULL

    SELECT IFNULL ( 
                    ( select distinct Salary 
                      from Employee
                      order by Salary desc
                      limit 1 offset 1 ) ,NULL) AS SecondHighestSalary
    

    延伸: IF表达式:IF(expr1,expr2,expr3) ,如果 expr1 是TRUE(expr1 != 0 and expr1 != NULL),则 IF( )的返回值为expr2 ; 否则返回值则为 expr3。IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定。
    IFNULL表达式:IFNULL(expr1,expr2) , 如果expr1 不为 NULL,则 IFNULL() 的返回值为 expr1 ; 否则其返回值为 expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。

    注:要IF语句前要加上SELECT才能将其中的数值提取出来

    limit 与offset 的区别:limit y 表示: 读取 y 条数据 ;limit x, y 表示: 跳过 x 条数据,读取 y 条数据; limit y offset x 表示: 跳过 x 条数据,读取 y 条数据。


    SQL自定义函数的使用:

    LeetCode第177题
    CREATE FUNCTION getNthHigherstSalary(N INT)RETURNS INT
    BEGIN
         SET N:=N-1
         RETURN(
                 SELECT salary
                 FROM employee
                 ORDER BY salary DESC
                 LIMIT N,1 ) ;
    END 
    

    注:要IF语句前要加上SELECT才能将其中的数值提取出来

    标量值函数定义格式: 详见 SQL server 自定义函数FUNCTION的使用_蓝星部队的博客-CSDN博客_sql server 函数


    DATE数据类型需要专门的时间处理函数例如DATEDIFF来处理


    SQL的delete操作:
    单表:

    DELETE  FROM   Person   WHERE    LastName = 'Wilson' 
    

    多表:
    从数据表t1中把那些在数据表t2里有匹配的记录全删除掉:

    DELETE   t1   FROM   t1,t2   WHERE   t1.id=t2.id   
    

    从数据表t1里在数据表t2里没有匹配的记录查找出来并删除掉:

    DELETE  t1  FROM  t1  LEFT JOIN  T2  ON   t1.id=t2.id  WHERE  t2.id  IS  NULL
    

    从两个表中找出相同记录的数据并把两个表中的数据都删除掉:

    DELETE  t1,t2   FROM   t1  LEFT JOIN  t2  ON  t1.id=t2.id  WHERE   t1.id=25
    

    Mysql DELETE 不能使用别名? 是我不会用! - 漠里 - 博客园


    LeetCode第626题

    这道题目实际上很简单:查询id和student,若id是偶数,减1;若id是奇数,加1;问题在于当总数为奇数时,最后一个id应保持不变,加1会导致空出一位。那么我们找到最后一位,让它保持不变就可以了。于是得到了下面的结果:

    SELECT
           IF( id % 2=0, 
                        id-1, 
                             if( id = (select count(distinct id) from seat ), id , id+1 ) )
           AS id , student
    FROM seat
    ORDER BY id
    

    SQL CASE WHEN 知识点:CASE WHEN 用法 - 简书

    LeetCode第627题 方法

    延伸:Update 语句: Update 语句用于修改表中的数据。

    UPDATE  表名称   
    SET   列名称 = 新值   
    WHERE   列名称 = 某值
    

    SQL UPDATE 语句


    Count ( ) 函数,可以放多个参数

    SELECT round(
    ifnull(
    (select count( distinct requester_id , accepter_id) from request_ accepted) /
    (select count(distinct sender_id ,send_to_id) from friend_ request)
    ,0)
    ,2) as accept_rate ;
    

    Order by所依据的列可以自定义

    Select 结束后才执行Order by ,Order by 的根据是指定的列,而本例后面跟的聚合函数值相当于一列。https://blog.csdn.net/u010002184/article/details/89601279

    SELECT question_ id AS 'survey_ 1og'
    FROM  survey_ _1og
    GROUP BY question_ id
    ORDER BY COUNT( answer_ id ) / COUNT( IF ( action = 'show', 1, 0) ) DESC
    LIMIT 1;
    
    SELECT `Name`
    FROM f
    ORDER BY S_days/Grade  DESC
    

    Where ( )也可以放多个参数

    Where ( a,b )in (   select  c,d from  ……   )
    

    SQL UNION 操作符

    UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

    请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

    SQL UNION 语法

    SELECT column_name(s) FROM table_name1
    UNION
    SELECT column_name(s) FROM table_name2
    

    注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

    示例:https://www.w3school.com.cn/sql/sql_union.asp

    此外,还能使用union来代替mysql没有的全连接


    Any , in , some , all , exists , not in 等是子查询关键词
    而max( ) , avg( ) , count( ) , min( ) , sum( ) , first( )等是聚合函数,配合group by使用


    相关文章

      网友评论

          本文标题:LeetCode 数据库笔记

          本文链接:https://www.haomeiwen.com/subject/iichcktx.html