LeetCode-SQL练习

SQL语句

lc175

1.join

inner join: 只取两者都有的部分

left join: 取左表

right join:取右表

outer join 取左右表并集

lc175

select FirstName, LastName, City, State from Person LEFT JOIN Address on Person.PersonId=Address.PersonId;

2.排序

 先按 height 降序排序,再按 name 升序排序
 SELECT name,height FROM tb_student_info ORDER BY height DESC,name ASC;

limit & offset

1. select* from article LIMIT 1,3

2.select * from article LIMIT 3 OFFSET 1

上面两种写法都表示取2,3,4三条条数据
当limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量,例如
当 limit后面跟一个参数的时候,该参数表示要取的数据的数量
例如 select* from article LIMIT 3  表示直接取前三条数据,类似sqlserver里的top语法。
例如select * from article LIMIT 3 OFFSET 1 表示跳过1条数据,从第2条数据开始取,取3条数据,也就是取2,3,4三条数据

lc176

取第二高的薪水:

注意这里distinct 去重

1.用临时表防范空值
SELECT
    (SELECT DISTINCT
            Salary
        FROM
            Employee
        ORDER BY Salary DESC
        LIMIT 1 OFFSET 1) AS SecondHighestSalary
;
假设我们有如图所示的数据,offset 1会超出范围 image
查询的结果为
{"headers": ["SecondHighestSalary"], "values": []}
而实际上预期结果为(以上可以达到)
{"headers": ["SecondHighestSalary"], "values": [[null]]}

2.用ifnull【在上面的外面又套了isnull】
ifnull(a,b)函数解释:
如果value1不是空,结果返回a
如果value1是空,结果返回b
SELECT
    IFNULL(
      (SELECT DISTINCT Salary
       FROM Employee
       ORDER BY Salary DESC
        LIMIT 1 OFFSET 1),
    NULL) AS SecondHighestSalary;

作者:LeetCode
链接:https://leetcode-cn.com/problems/second-highest-salary/solution/di-er-gao-de-xin-shui-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

lc177

第N高的薪水。

本来想取前N然后倒过来,但是如果

      select salary  from (select distinct salary from Employee order by salary desc limit N) B order by salary limit 1

这里需要在return外面做运算。

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
      SET N=N-1;
  RETURN (
      # Write your MySQL query statement below.

SELECT
    IFNULL(
      (SELECT DISTINCT Salary
       FROM Employee
       ORDER BY Salary DESC
        LIMIT 1 OFFSET N),
    NULL) AS SecondHighestSalary

  );
END

lc178

编写一个 SQL 查询来实现分数排名。

如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。

+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+
例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+
重要提示:对于 MySQL 解决方案,如果要转义用作列名的保留字,可以在关键字之前和之后使用撇号。例如 `Rank`

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rank-scores
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

表取别名。

select a.Score as Score,
(select count(distinct b.Score) from Scores b where b.Score >= a.Score) as 'Rank'
from Scores a
order by a.Score DESC;
 因为这个版本不允许使用Rank做子表名,解决方法是添加单引号. rank是mysql中的关键字,变成'Rank'就能通过

作者:johnbear007
链接:https://leetcode-cn.com/problems/rank-scores/solution/fen-cheng-liang-ge-bu-fen-xie-hui-rong-yi-hen-duo-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

函数

# Write your MySQL query statement below
select Score ,dense_rank() over( order by S.Score desc) as "Rank" from Scores S

作者:yi-qie-cong-jian
链接:https://leetcode-cn.com/problems/rank-scores/solution/dense_rank-han-shu-he-rankhan-shu-de-qu-267eh/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

值得注意的三个窗口函数。现在给定五个成绩:99,99,85,80,75。
DENSE_RANK()。如果使用 DENSE_RANK() 进行排名会得到:1,1,2,3,4。
RANK()。如果使用 RANK() 进行排名会得到:1,1,3,4,5。
ROW_NUMBER()。如果使用 ROW_NUMBER() 进行排名会得到:1,2,3,4,5。

作者:superkakayong
链接:https://leetcode-cn.com/problems/rank-scores/solution/zi-jie-ti-ku-178-zhong-deng-sqlfen-shu-pai-ming-1s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

窗口函数:https://zhuanlan.zhihu.com/p/138282683

over不能单独使用,要和分析函数:rank(),dense_rank(),row_number()等一起使用。

#按班级分类,将成绩降序排序
SELECT*,
rank() over ( PARTITION BY 班级 ORDER BY 成绩 DESC)  AS ranking  
FROM class; 
  • 窗口函数这里的“窗口”表示范围,可以理解为将原数据划分范围,即分组,然后用函数实现某些目的
  • 窗口函数有分组和排序的功能
  • 不减少原表的行数

having关键字

from : https://www.cnblogs.com/chenziyu/p/9253931.html

sql中的having语句是在使用group by的时候使用的。

通常where语句是在group by之前做数据筛选的,而having语句是对group by之后的结果进行筛选的。

例如:

从商品销售表里取得用户A购买的各种商品的总数:

SELECT
    SUM(TOTAL)
FROM
    COST
WHERE
    USERID = 'A'
GROUP BY 
    PRODUCTID
 

从商品销售表里取得用户A购买的各种商品的总数,并且改总数大于10:

SELECT
    SUM(TOTAL)
FROM
    COST
WHERE
    USERID = 'A'
GROUP BY
    PRODUCTID
HAVING
    SUM(TOTAL) > 10

lc 181

Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。

+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+
给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。

+----------+
| Employee |
+----------+
| Joe      |
+----------+

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/employees-earning-more-than-their-managers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/solution/chao-guo-jing-li-shou-ru-de-yuan-gong-by-leetcode/

1.
select a.name as Employee from Employee as a ,Employee as b where a.Salary >b.Salary and a.managerId = b.Id;
2.join
SELECT
     a.NAME AS Employee
FROM Employee AS a JOIN Employee AS b
     ON a.ManagerId = b.Id
     AND a.Salary > b.Salary
;

作者:LeetCode
链接:https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/solution/chao-guo-jing-li-shou-ru-de-yuan-gong-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

lc 182

编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

示例:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | [email protected] |
| 2  | [email protected] |
| 3  | [email protected] |
+----+---------+
根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| [email protected] |
+---------+

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/duplicate-emails
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

用了group by & having

1.me
select distinct a.Email from Person as a,Person as b where a.Email=b.Email and a.Id<>b.Id;
2.
select Email from
(
  select Email, count(Email) as num
  from Person
  group by Email
) as statistic
where num > 1
;
3.
select Email
from Person
group by Email
having count(Email) > 1;
作者:LeetCode
链接:https://leetcode-cn.com/problems/duplicate-emails/solution/cha-zhao-zhong-fu-de-dian-zi-you-xiang-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

lx 183

某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

Customers 表:

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+
Orders 表:

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+
例如给定上述表格,你的查询应返回:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/customers-who-never-order
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
select name as Customers from Customers where id not in (select CustomerId as id from Orders);

184

Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+
Department 表包含公司所有部门的信息。

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+
编写一个 SQL 查询,找出每个部门工资最高的员工。对于上述表,您的 SQL 查询应返回以下行(行的顺序无关紧要)。

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
+------------+----------+--------+
解释:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/department-highest-salary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
  • JOIN: 如果表中有至少一个匹配,则返回行
  • LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
  • RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
  • FULL JOIN: 只要其中一个表中存在匹配,就返回行

这个题用left join不对,join对了。原因:join 即inner join,员工有公司无就不返回了。但是left join,员工有公司无还会返回无公司的员工。

where 后面的语句没有想到。

# Write your MySQL query statement below
select Department.name as Department, Employee.name as Employee ,Salary from Employee join Department
on Department.id=Employee.DepartmentId WHERE
    (Employee.DepartmentId , Salary) IN
    (   SELECT
            DepartmentId, MAX(Salary)
        FROM
            Employee
        GROUP BY DepartmentId
    )
;


select d.name as Department,a.name as Employee, a.salary as Salary from Employee a,Department d,(select max(Salary) as ms,DepartmentId  from Employee group by DepartmentId ) c where a.DepartmentId=d.id and d.id=c.DepartmentId and a.Salary=c.ms;

遇到的题

一条SQL 语句 查询出每门课都大于80 分的学生姓名。
table:grades
name course score
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 语文 81
王五 数学 100

需要反向思维

select distinct name from grades where name not in (select distinct name from table where score<=80)

你可能感兴趣的:(LeetCode-SQL练习)