联表查询
select `firstName`,`lastName`,`city`,`state`
from Person p
left join Address a
on p.`PersonId` = a.`PersonId`;
自链接
select a.name as Employee
from Employee as a, Employee as b
where a.managerId = b.id
and a.salary > b.salary;
分组 + 过滤
select Email
from Person
group by email
having count(email) > 1;
联表查询
select name as `Customers`
from Customers as a
left join Orders as b
on a.Id = b.CustomerId
where b.CustomerId is null;
嵌套查询
select name as `Customers`
from Customers
where id not in(
select CustomerId from Orders
);
删除
delete p1 from Person p1, Person p2
where p1.email = p2.email
and p1.id > p2.id;
自链接
-- datediff():计算两个日期的天数差
select w1.id from Weather as w1, Weather as w2
where datediff(w1.recordDate, w2.recordDate) = 1
and w1.Temperature > w2.Temperature;
分组 + 聚合函数
select player_id, min(event_date) as first_login
from Activity
group by player_id
联表查询
select name, bonus
from Employee e
left join Bonus b
on e.empId = b.empId
where bonus < 1000
or bonus is null;
操作符<> + 逻辑运算符is null
select name from customer
where referee_id <> 2
or referee_id is null;
分组 + 聚合函数count(*) + 排序 + 分页
select customer_number
from Orders
group by customer_number
order by count(*) desc
limit 1;
where + or
select name, population, area
from World
where area >= 3000000
or population >= 25000000;
连接子查询union
select name, population, area from World
where area >= 3000000
union
select name, population, area from World
where population >= 25000000;
分组 + 过滤
select class from Courses
group by class
having count(*) >= 5;
嵌套查询 + 联表查询
select name from SalesPerson
where sales_id not in(
select sales_id from Orders o
left join Company c
on o.com_id = c.com_id
where c.name = "RED"
);
IF函数
select x, y, z, if(x + y > z and y + z > x and z + x > y, "Yes", "No") as triangle
from Triangle;
case ··· when ···
select x, y, z,
case
when x + y > z and y + z > x and z + x > y then "Yes"
else "No"
end
as triangle
from Triangle
自查询 + 聚合函数max
-- 当从一个子查询或派生表中检索数据时,必须为该子查询或派生表指定别名。
-- 使用聚合函数可以让它出现NULL。
select max(num) as num from (
select num from MyNumbers
group by num
having count(num) = 1
) as t;
聚合函数mod
select * from cinema
where description <> "boring"
and mod(id, 2) = 1
order by rating desc;
IF函数
update Salary
set sex = if(sex = 'm', 'f', 'm');
分组 + 分组后过滤
select actor_id, director_id
from ActorDirector
group by actor_id, director_id
having count(*) >= 3;
联表查询
select product_name, year, price
from Product p
inner join Sales s
on s.product_id = p.product_id;
ROUND() :用于对指定数字进行四舍五入操作。
select project_id, round(avg(experience_years), 2) as average_years
from Project p, Employee e
where p.employee_id = e.employee_id
group by project_id
分组 + 分组后过滤 + 聚合函数min() max()
select p.product_id, p.product_name
from Product p
left join Sales s
on p.product_id = s.product_id
group by p.product_id
having min(sale_date) >= '2019-01-01'
and max(sale_date) <= '2019-03-31';
去重distinct + 分组后过滤
select activity_date day, count(distinct user_id) active_users
from Activity
group by activity_date
having activity_date > '2019-06-27'
and activity_date <= '2019-07-27'
去重distinct + 排序
select distinct author_id id
from Views
where author_id = viewer_id
order by id asc
case…when… + sum函数 + 分组 + 排序
当一个单元格中有多个数据时,case when只会提取当中的第一个数据。
以CASE WHEN month=‘Feb’ THEN revenue END 为例,当id=1时,它只会提取month对应单元格里的第一个数据,即Jan,它不等于Feb,所以找不到Feb对应的revenue,所以返回NULL。
那该如何解决单元格内含多个数据的情况呢?答案就是使用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如SUM()或MAX(),而每个聚合函数的输入就是每一个多数据的单元格。
以SUM(CASE WHEN month=‘Feb’ THEN revenue END) 为例,当id=1时,它提取的Jan、Feb、Mar,从中找到了符合条件的Feb,并最终返回对应的revenue的值,即7000。
select id,
sum(case when month = 'Jan' then revenue end) as Jan_Revenue,
sum(case when month = 'Feb' then revenue end) as Feb_Revenue,
sum(case when month = 'Mar' then revenue end) as Mar_Revenue,
sum(case when month = 'Apr' then revenue end) as Apr_Revenue,
sum(case when month = 'May' then revenue end) as May_Revenue,
sum(case when month = 'Jun' then revenue end) as Jun_Revenue,
sum(case when month = 'Jul' then revenue end) as Jul_Revenue,
sum(case when month = 'Aug' then revenue end) as Aug_Revenue,
sum(case when month = 'Sep' then revenue end) as Sep_Revenue,
sum(case when month = 'Oct' then revenue end) as Oct_Revenue,
sum(case when month = 'Nov' then revenue end) as Nov_Revenue,
sum(case when month = 'Dec' then revenue end) as Dec_Revenue
from Department
group by id
order by id;
round函数 + 聚合函数 + if函数 + 分组
select query_name,
round(avg(rating / position), 2) quality,
round(sum(if(rating < 3, 1, 0)) / count(*) * 100, 2) poor_query_percentage
from Queries
group by query_name
round函数 + 聚合函数 + 分组 + 联表查询 + between
select p.product_id, round(sum(price * units)/sum(units), 2) average_price
from Prices p
left join UnitsSold u
on p.product_id = u.product_id
and purchase_date between start_date and end_date
group by p.product_id
联表查询 + 分组 + 排序 + 聚合函数 + cross join:它可以通过将一个表中的每一行与第二个表中的所有行组合来创建一个结果集。
select s.student_id, s.student_name, sub.subject_name,
count(e.subject_name) as attended_exams
from Students s
cross join Subjects sub
left join Examinations e
on s.student_id = e.student_id
and sub.subject_name = e.subject_name
group by s.student_id, sub.subject_name
order by s.student_id ASC;
联表查询 + 分组后过滤 + 聚合函数
select product_name, sum(unit) as unit
from Products p
left join Orders o
on p.product_id = o.product_id
where order_date between '2020-02-01' and '2020-2-29'
group by product_name
having sum(unit) >= 100;
联表查询
select unique_id, name
from Employees a
left join EmployeeUNI b
on a.id = b.id
联表查询 + ifnull()函数 + 分组 + 排序
select name, ifnull(sum(distance), 0) travelled_distance
from Users u
left join Rides r
on u.id = r.user_id
group by u.id
order by sum(distance) desc, name asc;
分组 + 去重 + group_concat()函数
select sell_date,
count(distinct product) num_sold,
group_concat(distinct product) products
from Activities
group by sell_date;
正则表达式
‘^’ 表示以后面的字符为开头;‘[]’ 表示括号内任意字符;‘-’ 表示连续;‘*’ 表示重复前面任意字符任意次数;
‘\ ’ 用来转义后面的特殊字符,以表示字符原本的样子,而不是将其作为特殊字符使用;’$’ 表示以前面的字符为结尾。
‘.’(点)这个玩意需要两次转义修饰。
select * from users
where mail REGEXP '^[a-zA-Z][a-zA-Z0-9\_\\.\-]*@leetcode\\.com$'
like模糊查询
select * from Patients
where conditions like '% DIAB1%'
or conditions like 'DIAB1%';
联表查询 + 分组
select customer_id, count(customer_id) as count_no_trans
from Visits v
left join Transactions t
on v.visit_id = t.visit_id
where transaction_id is null
group by customer_id;
联表查询 + 分组后过滤
select name, sum(amount) as balance
from Users u
left join Transactions t
on u.account = t.account
group by name
having sum(amount) > 10000;
嵌套查询 + round函数 + 聚合函数 + 分组
select
contest_id,
round(100*count(user_id)/(select count(*) from users),2) as percentage
from Register
group by contest_id
order by 2 desc, 1;
分组 + 聚合函数 + ROUND函数 + IF函数
select
machine_id,
round(avg(if(activity_type='start',-timestamp,timestamp))*2,3) processing_time
from Activity
group by machine_id;
concat、upper、lower、left、substring函数
select
user_id,
concat(upper(left(name,1)),lower(substring(name,2))) name
from Users
order by user_id;
length函数
select tweet_id from Tweets
where length(content) > 15;
分组 + 聚合函数
select date_id, make_name,
count(distinct lead_id) unique_leads, count(distinct partner_id) unique_partners
from DailySales
group by date_id, make_name;
分组 + 聚合函数
select user_id, count(follower_id) followers_count
from Followers
group by user_id
order by user_id;
自链接 + 去重 + 聚合函数 + 分组 + 排序
select distinct a.reports_to employee_id, b.name,
count(a.reports_to) reports_count,
round(avg(a.age)) average_age
from Employees a, Employees b
where a.reports_to = b.employee_id
group by a.reports_to
order by a.reports_to;
分组 + 聚合函数
select event_day day, emp_id, sum(out_time - in_time) total_time
from Employees
group by event_day, emp_id;
条件查询
select product_id from Products
where low_fats = 'Y'
and recyclable = 'Y';
分组 + 连接查询union
select employee_id, department_id
from Employee
group by employee_id
having count(*) = 1
union
select employee_id, department_id
from Employee
where primary_flag = 'Y';
列转行 + 连接查询union + 新增的中间列:‘store1’ as store
select product_id, 'store1' store, store1 price
from Products
where store1 is not null
union
select product_id, 'store2' store, store2 price
from Products
where store2 is not null
union
select product_id, 'store3' store, store3 price
from Products
where store3 is not null;
补充:行转列:
SELECT
product_id,
SUM(IF(store = 'store1', price, NULL)) 'store1',
SUM(IF(store = 'store2', price, NULL)) 'store2',
SUM(IF(store = 'store3', price, NULL)) 'store3'
FROM
Products1
GROUP BY product_id ;
left函数(用于从左边开始截取指定长度的子字符串) + 排序
也可以使用like查询匹配名字,mod函数取余。
select
employee_id,
if(employee_id % 2 = 1 and left(name, 1) != 'M', salary, 0) bonus
from Employees
order by employee_id;
分组 + 聚合函数 + year函数
select user_id, max(time_stamp) last_stamp
from Logins
where year(time_stamp) = '2020'
group by user_id;
联表查询 + union + 排序
select employee_id
from(
select e.employee_id
from Employees e
left join Salaries s
on e.employee_id = s.employee_id
where salary is null
union
select s.employee_id
from Salaries s
left join Employees e
on e.employee_id = s.employee_id
where name is null
) as r
order by employee_id;
union all + 分组后过滤 + 排序
select employee_id
from(
select employee_id from Employees
union all
select employee_id from Salaries
) as r
group by employee_id
having count(*) = 1
order by employee_id;
子查询
select employee_id
from Employees
where salary < 30000
and manager_id not in (
select employee_id from Employees
)
order by employee_id;
分组 + 聚合函数
select teacher_id, count(distinct subject_id) cnt
from Teacher
group by teacher_id;