mysql的安装:
https://blog.csdn.net/submarineas/article/details/89762584 windows下mysql的安装
https://blog.csdn.net/submarineas/article/details/86532966 Linux下mysql的安装
Navicat的使用总结:
https://blog.csdn.net/submarineas/article/details/90271858
Navicat使用技巧
2019/8/5:查找重复的电子邮箱与大国
查找重复的电子邮箱
关于查找重复电子邮箱,意思很直白,什么时候可以判断为重复?当email相同或者用count统计出email数量为2即以记为重复,那么便有两种方式可以写了:
select Email from email group by Email having count(Email) >= 2
select DISTINCT A.Email from email A,email B where A.Email = B.Email and A.id != B.id
关于上面sql中having和where可以互换位置嘛,我又特意去试了一下,发现会报Group function is not allowed here,因为sql的执行顺序为from子句 ——> where 子句 ——> group by 子句 ——> having 子句 ——> order by 子句 ——> select 子句
关于select的查询操作,我之前也有总结一篇博客,只不过后来没怎么用sql了,然后到今天我重新翻看才发现还没有总结完:
mysql(3):查询基础总结
查找大国:
通过这句话:如果一个国家的面积超过300万平方公里,或者(人口超过2500万并且gdp超过2000万),那么这个国家就是大国家。
就可以直接写出sql了:
select name,population,area
from world
where population>25000000
or area>3000000;
2019/8/7:连续出现的数字与超过经理收入的员工
连续出现的数字
题目说明:
编写一个 SQL 查询,查找所有至少连续出现三次的数字。
https://leetcode-cn.com/problems/consecutive-numbers/
最简单的一种思路便是通过自身连续连表三次,和上面的电子邮件题一样,然后判断id和num,以上题email中的数据,那么我们便可以写出sql:
select distinct a.Email ConsecutiveNums
from email a,email b,email c
where a.Email=b.Email
and b.Email=c.Email
and a.Id+1=b.Id
and b.Id+1=c.Id
另外这里的去重也可以用group by,都一样,然后我看到一种使用用户变量的方式进行判断的,感觉很强,在这里记录一下,方便之后学完变量后回看:
select distinct Num as ConsecutiveNums
from (
select Num,
case
when @prev = Num then @count := @count + 1
when (@prev := Num) is not null then @count := 1
end as CNT
from Logs, (select @prev := null,@count := null) as t
) as temp
where temp.CNT >= 3
超过经理收入的员工
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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
然后我们便可以写出sql为:
select B.name as Employee
from Employee A,Employee B
where A.id = B.ManagerId
and A.Salary < B.Salary;
看了下leetcode官方题解,发现还能换成join:
SELECT
a.NAME AS Employee
FROM Employee AS a JOIN Employee AS b
ON a.ManagerId = b.Id
AND a.Salary > b.Salary
2019/8/8:超过5名学生的课与交换工资
超过5名学生的课
有一个courses 表 ,有: student (学生) 和 class (课程)。
请列出所有超过或等于5名学生的课。
例如,表:
+---------+------------+
| student | class |
+---------+------------+
| A | Math |
| B | English |
| C | Math |
| D | Biology |
| E | Math |
| F | Computer |
| G | Math |
| H | Math |
| I | Math |
+---------+------------+
应该输出:
+---------+
| class |
+---------+
| Math |
+---------+
note:学生在每个课中不应被重复计算。
开始没有看到那句note,导致忘记筛选重复值,而当进行到第四个测试用例的时候出现了报错,即当有两个A选了math的时候只能算一个,然后看到这个用例的时候,我在后面的条件中加了去重,然后可以了:
{"headers": {"courses": ["student", "class"]}, "rows": {"courses": [["A", "Math"], ["B", "English"], ["C", "Math"], ["D", "Biology"], ["E", "Math"], ["F", "Math"], ["A", "Math"]]}}
select class from courses group by class having count(distinct student) >= 5;
这里看到一个网友通过正向推导的三步,感觉很强,我上面是直接反向了,因为逻辑更简单,正向也不一定能推出来,所以在这里记录一下:
#共三种写法
#最朴实的写法,共三层查询,先利用 DISTINCT 去掉重复记录得到表 A,再利用 GROUP BY 为 CLASS 分组,然
#后用 COUNT() 统计每组个数得到表 B,最后在最外层限定数量 >=5 查到结果
SELECT B.CLASS #最外层
FROM (SELECT A.CLASS,COUNT(A.CLASS) C #第二层查询,得到具有 CLASS、COUNT(CLASS) 的表 B
FROM (SELECT DISTINCT * #第三层查询,去重得到表 A
FROM COURSES) A
GROUP BY A.CLASS) B #分组
WHERE B.C >= 5; #条件
#稍微优化,两层查询,主要是因为用了 HAVING 省了一层查询
SELECT A.CLASS #最外层
FROM (SELECT DISTINCT * #第二层查询,去重得到表 a
FROM COURSES) A
GROUP BY A.CLASS #分组
HAVING COUNT(A.CLASS) >= 5; #利用 COUNT() 计算每组个数并筛选
#极致优化,一层查询,利用 GROUP BY 为 CLASS 分组后,直接用 COUNT() 统计每组学生个数,在统计前先用
#DISTINCT 去掉重复学生
SELECT CLASS
FROM COURSES
GROUP BY CLASS #分组
HAVING COUNT(DISTINCT STUDENT) >= 5; #利用 COUNT() 统计每门课 STUDENT 的个数,同时利
#用 DISTINCT 去掉重复学生、
交换工资
给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。
注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。
通过注意这句话基本否定了向select想的思路,同时也减少了很多复杂的操作,我也不至于去想,那么既然要满足男性与女性交换工资,在python中通过if else进行,那么mysql中有同样操作常见的便是case when了,关于update的语法格式如下:
update table
set 字段1=case
when 条件1 then 值1
when 条件2 then 值2
else 值3
end
where ……
update salary
set sex=case sex
when "m" then "f"
when "f" then "m" # 或者是else "m"
end
另外翻出我去年为了背面试题画的mysql思维导图,现在感觉接近忘了一半。。最近又要重新开始记了。
有趣的电影
某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。
作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片描述为非 boring (不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating 排列。
这题讲得很通俗了,非boring、id为奇数、按rating排序(降序)。所以可以写出sql为:
select id,movie,description,rating from cinema where cinema.description != "boring" and id % 2 = 1 order by rating desc;
# 另外看到官方题解使用 MOD() 函数,感觉差不多
2019/8/9(实际是8,提前批):组合两张表和从不订购的客户
组合两张表
编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:
这题考虑的是怎样选择一种连接方式使得Adress表中地址id为空时,表连接关系依然成立,可以看我最上面分享的sql查询中的一张图,我中间也忘了,然后看着这张图想起来怎么做,这里引用一下:
select FirstName, LastName, City, State from Person left join Address on Address.PersonId = Person.PersonId;
从不订购的客户
某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
https://leetcode-cn.com/problems/customers-who-never-order/
这题就是上图的位于左中和右中的两张图,即有一边的null为空,而另一边排除掉这一部分,所以sql为:
select A.Name as Customers from Customers A left join Orders B on A.Id=B.CustomerId WHERE B.CustomerId is null;
删除重复的邮箱
编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
https://leetcode-cn.com/problems/delete-duplicate-emails/
写了半天,发现无论怎么写都是全部的值,然后跑去看题解,发现原来这题竟然是要写删除。。。好吧,没看懂需求,卡得心累,还瞎写了半天子查询,然而没有删除的操作根本判断不了。。直接上官方题解吧:
DELETE p1 FROM Person p1,Person p2 WHERE p1.Email = p2.Email AND p1.Id > p2.Id
好像今天刷了8题,从下午3点到接近9点,6道sql和2道python,可能中途有比较急的地方,接下来还要花一段时间再过一遍了。
2019/8/9:分数排名与换座位
分数排名
编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
链接:https://leetcode-cn.com/problems/rank-scores
这题可以按正向走或者反向走,刚开始看题没有想明白这回事,大概猜到是自连接但写了很久没写出来,然后看了下题解,发现我忽略了一点,即如果要算当前排名,那么只需要推导出比它大的非重复个数就知道它排第几了,那么sql为:
select s.Score,(select count(distinct Score)
from Scores where Score>=s.Score) # 查看当前比自己大的去重后的个数
as Rank from Scores s
order by s.Score desc
select s1.Score, count(distinct(s2.Score)) Rank
from Scores s1, Scores s2
where s1.Score<=s2.Score
group by s1.Id
如果理解了题目意思,第二句更容易写出来。
换座位
小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。
其中纵列的 id 是连续递增的
小美想改变相邻俩学生的座位。
你能不能帮她写一个 SQL query 来输出小美想要的结果呢?
链接:https://leetcode-cn.com/problems/exchange-seats
这题概念很模糊,和上面的交换工资很类似,但这里的名字是字符串,而上面的性别可以看成是boolean布尔值,所以应该是用case when,但具体怎么写,还有特意强调id是自增的以及奇数最后一个不排,这个就不太会了,可能概念记得浅,这题甚至没敢动手,然后去看了下答案发现还行吧,理解起来也有点难度,日后回顾:
SELECT * FROM(
SELECT id-1 AS id,student FROM seat WHERE id%2=0
# 如果是偶数,那么id数-1,即所有偶数同学向前坐
UNION
SELECT id+1 AS id,student FROM seat WHERE id%2=1 AND (id+1) <= (SELECT COUNT(*) FROM seat)
# 当id数是奇数且不大于且id数加一不大于总座位数时,将id数+1,学生向后坐
UNION
SELECT id AS id,student FROM seat WHERE id%2=1 AND (id+1) > (SELECT COUNT(*) FROM seat)
# 当id数是奇数且id数加一大于总座位数时,id数不变。没有多余位子换了,这个学生不动
) AS T1
ORDER BY id ASC
2019/8/10:部门工资最高的员工与部门工资前三高的所有员工
部门工资最高的员工
Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。
+----+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Henry | 80000 | 2 |
| 3 | Sam | 60000 | 2 |
| 4 | Max | 90000 | 1 |
+----+-------+--------+--------------+
Department 表包含公司所有部门的信息。
+----+----------+
| Id | Name |
+----+----------+
| 1 | IT |
| 2 | Sales |
+----+----------+
编写一个 SQL 查询,找出每个部门工资最高的员工。例如,根据上述给定的表格,Max 在 IT 部门有最高工资,Henry 在 Sales 部门有最高工资。
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/department-highest-salary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
前面都能写出来,都是常见的套路,但在建立第三张表的时候,没有建立出来,应该说是迟疑了,或者说当时脑子里思绪是不用这么麻烦?还是练得太少,一多想,思路就会变得杂乱无章,另外看了下官方题解,发现确实不用第三张表也行,然而我就不太理解in的用法了,可能我用的太少,它的这种用法确实巧妙:
select
B.Name as Department,
A.Name as Employee,
C.max_salary as Salary
from Employee A,Department B,
(select DepartmentId,MAX(Salary) as max_salary from Employee C group by DepartmentId) as C
where A.DepartmentId = B.Id and A.Salary = C.max_salary and A.DepartmentId = C.DepartmentId
上述是看了一些题解,我发现还是这种比较好理解一些,所以就自己再写了一遍,最后一定不要忘了还有一个条件,就是A.DepartmentId = C.DepartmentId,否则结果会出现Employee 表的笛卡尔积。
然后官方给的题解我觉得不是很好理解,可能我还是对sql语法有些不熟,在这里记录一下:
SELECT
Department.name AS 'Department',
Employee.name AS 'Employee',
Salary
FROM
Employee
JOIN
Department ON Employee.DepartmentId = Department.Id
WHERE
(Employee.DepartmentId , Salary) IN
( SELECT
DepartmentId, MAX(Salary)
FROM
Employee
GROUP BY DepartmentId
)
部门工资前三高的所有员工
Employee 表包含所有员工信息,每个员工有其对应的工号 Id,姓名 Name,工资 Salary 和部门编号 DepartmentId 。
https://leetcode-cn.com/problems/department-top-three-salaries/
题目太长不复制全部了,这题感觉要考虑的情况就多了,然而依然没有一个能有一个比较清晰的想法贯穿我的整个思维,讲得普通点,就是想不出来咯。。。先放在这里,晚上再想一下。
第二天:看了下官方题解,类比最高工资和分数排名,懂了思路:
SELECT
d.Name AS 'Department', e1.Name AS 'Employee', e1.Salary
FROM
Employee e1
JOIN
Department d ON e1.DepartmentId = d.Id
WHERE
3 > (SELECT
COUNT(DISTINCT e2.Salary)
FROM
Employee e2
WHERE
e2.Salary > e1.Salary
AND e1.DepartmentId = e2.DepartmentId
)
;
然后又挑了一个比较好理解的,在这里记录一下:
select dptm.Name as Department, emp1.Name as Employee, emp1.Salary
from Employee emp1
join Employee emp2 on emp1.DepartmentId = emp2.DepartmentId and emp1.Salary <= emp2.Salary
join Department dptm on emp1.DepartmentId = dptm.Id
group by emp1.Id
having count(distinct emp2.Salary) <= 3
order by dptm.Id, emp1.Salary desc, emp1.Id
2019/8/11:第二高的薪水和第N高的薪水
第二高的薪水
编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。
+----+--------+
| Id | Salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+
例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。
+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+
链接:https://leetcode-cn.com/problems/second-highest-salary
这题看完题目就大概猜到用哪个函数,当前也不是没想过正向把这题解出来,正向的方法大概可以先找出第一个然后排除,再从排除里的找到最大的那个就是第二,但那样效率太低,不过如果不存在的话就不需要多加判断了。我还是先从limit函数走吧,因为很少用,正好这里复习一下:
分页的其他使用:offset
SQL查询语句中的 limit 与 offset 的区别:
limit y 分句表示: 读取 y 条数据
limit x, y 分句表示: 跳过 x 条数据,读取 y 条数据
limit y offset x 分句表示: 跳过 x 条数据,读取 y 条数据
然后可以写出sql:
select
IFNULL((select distinct Salary from Employee order by Salary desc limit 1,1),null)
as SecondHighestSalary
# 可以先写出一个简单版本,不包含ifnull的,这个我也是后来才看到如果是没有第二个则为null
SELECT MAX(Salary) AS SecondHighestSalary
FROM Employee
where salary < (
SELECT MAX(Salary)
FROM Employee
)
# 这种就是正向查询了,也就是先找第一个再找第二个,但如果是第三个就很难写了,所以推荐还是第一种写法
第N高的薪水
没有思路,看了下题解,原来是用函数:
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
DECLARE M INT;
SET M=N-1;
RETURN (
# Write your MySQL query statement below.
SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT M, 1
);
END
知道有这么个概念,但从来没用过,这里记录一下,以后回来复习。
2019/8/12:上升的温度和叶节点
上升的温度
给定一个 Weather 表,编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。
+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+---------+------------------+------------------+
例如,根据上述给定的 Weather 表格,返回如下 Id:
+----+
| Id |
+----+
| 2 |
| 4 |
+----+
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rising-temperature
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这里看着是简单题,然而不太懂日期里面的相应函数,想到了是要日期相比,否则不可能给这个字段,但还是没有想到哪个函数,然后看了下题解,使用DATEDIFF:可以计算两个日期的时间差。
SELECT
weather.id AS 'Id'
FROM
weather
JOIN
weather w ON DATEDIFF(weather.date, w.date) = 1
AND weather.Temperature > w.Temperature
树节点
对于 tree 表,id 是树节点的标识,p_id 是其父节点的 id。
+----+------+
| id | p_id |
+----+------+
| 1 | null |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
+----+------+
每个节点都是以下三种类型中的一种:
Leaf: 如果节点是根节点。
Root: 如果节点是叶子节点。
Inner: 如果节点既不是根节点也不是叶子节点。
写一条查询语句打印节点id及对应的节点类型。按照节点id排序。上面例子的对应结果为:
+----+------+
| id | Type |
+----+------+
| 1 | Root |
| 2 | Inner|
| 3 | Leaf |
| 4 | Leaf |
| 5 | Leaf |
+----+------+
说明:
节点’1’是根节点,因为它的父节点为NULL,有’2’和’3’两个子节点。
节点’2’是内部节点,因为它的父节点是’1’,有子节点’4’和’5’。
节点’3’,‘4’,'5’是叶子节点,因为它们有父节点但没有子节点。
下面是树的图形:
1
/ \
2 3
/ \
4 5
注意:
如果一个树只有一个节点,只需要输出根节点属性。
这题可以看成是二叉树的数据结构在sql中的应用,题目意思是需要我们针对二叉树的结构来定义他们相应节点的名词,然后我们就可以用case when来分别对上述的三种情况标号:
select t1.id,
case
when t1.p_id is Null then 'Root'
when (select count(*) from tree t2 where t1.id = t2.p_id) = 0
then 'Leaf'
when (select count(*) from tree t3 where t1.id = t3.p_id) > 0
then 'Inner'
end as Type
from tree t1
2019/8/15:最后三题
查询回答率最高的问题
求出survey_log表中回答率最高的问题,表格的字段有:uid, action, question_id, answer_id, q_num, timestamp。
uid是用户id;action的值为:“show”, “answer”, “skip”;当action是"answer"时,answer_id不为空,相反,当action是"show"和"skip"时为空(null);q_num是问题的数字序号。
写一条sql语句找出回答率最高的问题。
https://leetcode-cn.com/problems/get-highest-answer-rate-question/
这题的比率一般都是可以直接相除,所以sql为:
select question_id as survey_log
from(
select (sum(case when `action` like 'answer' then 1 else 0 end) / sum(case when `action` like 'show' then 1 else 0 end)) as rate,question_id
from survey_log
group by question_id
order by rate desc
limit 1) x
平面上最近距离
point_2d 表包含一个平面内一些点(超过两个)的坐标值(x,y)。
写一条查询语句求出这些点中的最短距离并保留2位小数。
链接:https://leetcode-cn.com/problems/shortest-distance-in-a-plane/
这个根据定义就可以直接写出了,运用欧氏距离,首先确立两表联查,然后再通过公式找到最小值,那么可以写出sql为:
select round(sqrt(min(power((p1.x-p2.x),2)+power((p1.y-p2.y),2))),2) as shortest
from point_2d p1,point_2d p2
where p1.x<>p2.x or p1.y<>p2.y
最后需要注意的是两表联查后选中的数不能相同,因为相同则是0,那么就没有意义。
行程与用户
Trips 表中存所有出租车的行程信息。每段行程有唯一键 Id,Client_Id 和 Driver_Id 是 Users 表中 Users_Id 的外键。Status 是枚举类型,枚举成员为 (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’)。
+----+-----------+-----------+---------+--------------------+----------+
| Id | Client_Id | Driver_Id | City_Id | Status |Request_at|
+----+-----------+-----------+---------+--------------------+----------+
| 1 | 1 | 10 | 1 | completed |2013-10-01|
| 2 | 2 | 11 | 1 | cancelled_by_driver|2013-10-01|
| 3 | 3 | 12 | 6 | completed |2013-10-01|
| 4 | 4 | 13 | 6 | cancelled_by_client|2013-10-01|
| 5 | 1 | 10 | 1 | completed |2013-10-02|
| 6 | 2 | 11 | 6 | completed |2013-10-02|
| 7 | 3 | 12 | 6 | completed |2013-10-02|
| 8 | 2 | 12 | 12 | completed |2013-10-03|
| 9 | 3 | 10 | 12 | completed |2013-10-03|
| 10 | 4 | 13 | 12 | cancelled_by_driver|2013-10-03|
+----+-----------+-----------+---------+--------------------+----------+
Users 表存所有用户。每个用户有唯一键 Users_Id。Banned 表示这个用户是否被禁止,Role 则是一个表示(‘client’, ‘driver’, ‘partner’)的枚举类型。
+----------+--------+--------+
| Users_Id | Banned | Role |
+----------+--------+--------+
| 1 | No | client |
| 2 | Yes | client |
| 3 | No | client |
| 4 | No | client |
| 10 | No | driver |
| 11 | No | driver |
| 12 | No | driver |
| 13 | No | driver |
+----------+--------+--------+
写一段 SQL 语句查出 2013年10月1日 至 2013年10月3日 期间非禁止用户的取消率。基于上表,你的 SQL 语句应返回如下结果,取消率(Cancellation Rate)保留两位小数。
+------------+-------------------+
| Day | Cancellation Rate |
+------------+-------------------+
| 2013-10-01 | 0.33 |
| 2013-10-02 | 0.00 |
| 2013-10-03 | 0.50 |
+------------+-------------------+
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trips-and-users
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
有些没懂意思,然后看一个题解看懂了:
select distinct b.Request_at as Day,Round(1-(select count(*)
from Trips a
where a.Client_Id not in(select Users_id from Users where Banned='Yes') and a.Driver_Id not in(select Users_id from Users where Banned='Yes') and a.Request_at=b.Request_at and a.Status='completed')/(select count(*)
from Trips a
where a.Client_Id not in(select Users_id from Users where Banned='Yes') and a.Driver_Id not in(select Users_id from Users where Banned='Yes') and a.Request_at=b.Request_at),2) as 'Cancellation Rate'
from Trips b
where b.Request_at>= '2013-10-01' and b.Request_at<='2013-10-03'
#1、内层计算每个日期No的总人数
#2、内层计算1中对应的complete人数
#3、内层1/2计算未取消的分数值,然后1-这个分数值,得到取消率
#4、由于内层日期不能人为指定,需要外层传入日期值
#5、在外层指定日期区间,因为内层指定了也没用(因为1-这个操作会导致日期区间失效)