美文网首页
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