Eg175 组合两个表
- 知识点: select … from table a (…) join table b on … = …
- 1)INNER JOIN (内连接,或JOIN): 只连接匹配的行
select * from table A inner join table B on A.key = B.key //内连接 - 2)LEFT JOIN (左连接):包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
- 3)RIGHT JOIN (右连接):包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
- 4)OUTER JOIN (外连接): 包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。
- 1)INNER JOIN (内连接,或JOIN): 只连接匹配的行
由于题目要求:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:,所以应该用LEFT JOIN 才会返回table A 有 而 table B 无(值为Null)的行
select p.FirstName, p.LastName, a.City, a.State from Person p left join Address a on p.PersonId = a.PersonId;
Eg176 第二高的薪水
即:输出某列中第二大的数字
- 知识点:
1.limit子句可以被用于强制select语句返回指定记录数
2.limit接受一个或两个整型参数
3.第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目
4.初始记录行的偏移量是0(不是1)
5.为了与pgsql兼容,MySQL也支持语法 limit # offset #
6.limit子句位于order by子句之后
- select distinct 可以保证元素不重复
- order by column 默认是升序排序,若需为降序,应为 order by column desc
方法一:
将该column的值降序(order by column desc),再限制(limit)从第1行后开始,仅输出1行(limit 1,1)
select distinct Salary SecondHighestSalary from Employee order by Salary desc limit 1,1
但是,当不存在第二高元素值时,上述并不返回null,与题目意思不符。
修正:
select (select distinct Salary from Employee order by Salary desc limit 1,1) as SecondHighestSalary
Eg181. 超过经理收入的员工
select Name Employee
from Employee as e
where Salary > (select
Salary from Employee
where
Id = e.ManagerId)
±—±------±-------±----------+
| Id | Name | Salary | ManagerId |
±—±------±-------±----------+
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | NULL |
| 4 | Max | 90000 | NULL |
±—±------±-------±----------+
分析:
数据库按照一行一行的模式对table进行扫描。现在目的是,对当前扫描的object,比较object.Salary 与 object.ManagerId 对应的Salary。如何保证,我第二次扫描的是上一次扫描的object.ManagerId呢?用实例对象e来指向。
Eg182 查找重复的邮箱
错误的想法:
select Email from Person.Personnel
where Email = any(select Email from Person.Personnel);
- 1)any()表示若有任何一个满足就返回
eg:
elect * from student where 班级=’01’ and age > any (select age from student where 班级=’02’);
就是说,查询出01班中,年龄大于 02班任意一个 的 同学 - 2) 如果没有any() 会报错:Subquery returns more than 1 row
正确做法:
select Email from Person
group by Email having
count(Email) > 1
- 1 )GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组
- 2 )GROUP BY必须得配合聚合函数来用,分组之后你可以计数(COUNT),求和(SUM),求平均数(AVG)等。
Eg.196 删除重复的电子邮箱
delete p1 from Person p1, Person p2
where p1.Email = p2.Email and p1.Id > p2.Id
- 分析:
from Person p1, Person p2即实例化两个对象p1,p2。这个对象是迭代的Person table的每条数据。实际上p1,p2都指向同一个对象(table Person)