You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
createtabletrips (
id int,
client_id int,
driver_id int,
city_id int,
status char(255),
request_at date
);
insert into trips values(1, 1, 10, 1, 'completed', '2013-10-01');
insert into trips values(2, 2, 11, 1, 'cancelled_by_driver', '2013-10-01');
insert into trips values(3, 3, 12, 6, 'completed', '2013-10-01');
insert into trips values(4, 4, 13, 6, 'cancelled_by_client', '2013-10-01');
insert into trips values(5, 1, 10, 1, 'completed', '2013-10-02');
insert into trips values(6, 2, 11, 6, 'completed', '2013-10-02');
insert into trips values(7, 3, 12, 6, 'completed', '2013-10-02');
insert into trips values(8, 2, 12, 12, 'completed', '2013-10-03');
insert into trips values(9, 3, 10, 12, 'completed', '2013-10-03');
insert into trips values(10, 4, 13, 12, 'cancelled_by_driver', '2013-10-03');
createtableusers (
users_id int,
banned char(255),
role char(255)
);
insert into users value(1, 'No', 'client');
insert into users value(2, 'Yes', 'client');
insert into users value(3, 'No', 'client');
insert into users value(4, 'No', 'client');
insert into users value(10, 'No', 'driver');
insert into users value(11, 'No', 'driver');
insert into users value(12, 'No', 'driver');
insert into users value(13, 'No', 'driver');
SQL:方法一
selecttrips.request_atas 日期,
round(sum(if(trips.status='completed', 0, 1)) /count(trips.status), 2) as 取消率
from trips
join users u1 ontrips.client_id=u1.users_idandu1.banned='No'join users u2 ontrips.driver_id=u2.users_idandu2.banned='No'wheretrips.request_at between '2013-10-01'and'2013-10-03'group by 日期;
解析
错误的思路:
if (client_id = users_id or driver_id = users_id) and users_id没有被禁止
...
只要 client_id 和 driver_id 只要有一个满足条件,就会被查出来
SQL 代码
select*from trips join users on (trips.client_id=users.users_idortrips.driver_id=users.users_id) andusers.banned='No';
这样查出的结果没有排除掉 users_id = 2 的用户
正确的思路:
if(client_id = users_id and users_id没有禁止
and driver_id = users_id and users_id没有被禁止)
...
client_id 和 driver_id 要分别和自己关联的 users_id 判断是否被禁止。
SQL 代码
select*from trips
join users u1 ontrips.client_id=u1.users_idandu1.banned='No'join users u2 ontrips.driver_id=u2.users_idandu2.banned='No';
selecttrips.request_atas 日期,
round(sum(if(trips.status='completed', 0, 1)) /count(trips.status), 2) as 取消率
from trips
left join (
select users_id from users where banned ='Yes'
) as a1 ontrips.client_id=a1.users_idleft join(
select users_id from users where banned ='Yes'
) as a2 ontrips.driver_id=a2.users_idwherea1.users_id is nullanda2.users_id is nullandtrips.request_at between '2013-10-01'and'2013-10-03'group by 日期;
解析
找出被禁止的用户
select users_id from users where banned ='Yes';
错误的思路:
select*from trips, (
select users_id from users where banned ='Yes'
) as a
wheretrips.client_id!=a.users_idandtrips.driver_id!=a.users_id
有两点错误:
没有考虑 a 表为空时,最后的结果是为空的
多个结果用 != 是查不出结果的
修改成这样就可以了
select*from trips wheretrips.client_idin (select users_id from users where banned ='No')
andtrips.driver_idin (select users_id from users where banned ='No');
如果不使用 in 需要换一种思路
正确的思路:
selecttrips.request_atas 日期,
round(sum(if(trips.status='completed', 0, 1)) /count(trips.status), 2) as 取消率
from trips
left join (
select users_id from users where banned ='Yes'
) as a1 ontrips.client_id=a1.users_idleft join (
select users_id from users where banned ='Yes'
) as a2 ontrips.driver_id=a2.users_idwherea1.users_id is nullanda2.users_id is nullandtrips.request_at between '2013-10-01'and'2013-10-03'group by 日期;
查出被禁止的用户作为表 a 和 trips 表做两次左连:
trips.client_id = a1.users_id
trips.driver_id = a2.users_id
因为 trips 作为主体表,和 a 表左连,连接的结果是被禁止的用户行程数据
而我们要的结果是非禁止用户的形成数据, a 中 users_id 为 null 的就是我们要的数据
所以最后的筛选条件是 a1.users_id is null and a2.users_id is null
这种写法还可以反过来写,查出没被禁止的用户 a 和 trips 做内连,就不会有 null 存在
selecttrips.request_atas 日期,
round(sum(if(trips.status='completed', 0, 1)) /count(trips.status), 2) as 取消率
from trips
join (
select users_id from users where banned ='No'
) as a1 ontrips.client_id=a1.users_idjoin (
select users_id from users where banned ='No'
) as a2 ontrips.driver_id=a2.users_idwheretrips.request_at between '2013-10-01'and'2013-10-03'group by 日期;
The text was updated successfully, but these errors were encountered:
题目
题目链接:行程和用户
查询出
2013-10-01
和2013-10-03
期间非禁止用户(乘客和司机都必须未被禁止)的取消率,非禁止用户即banned
为No
的用户,禁止用户即banned
为Yes
的用户。取消率需要四舍五入保留两位小数
其中
client_id
和driver_id
对应users
表中的users_id
SQL:方法一
解析
错误的思路:
只要
client_id
和driver_id
只要有一个满足条件,就会被查出来SQL
代码这样查出的结果没有排除掉
users_id = 2
的用户正确的思路:
client_id
和driver_id
要分别和自己关联的users_id
判断是否被禁止。SQL
代码Tips
if
语法:if(expr1, expr2, expr3)
如何expr1
为true
则输出为expr2
否则输出为expr3
SQL:方法二
解析
找出被禁止的用户
错误的思路:
有两点错误:
a
表为空时,最后的结果是为空的!=
是查不出结果的修改成这样就可以了
如果不使用
in
需要换一种思路正确的思路:
查出被禁止的用户作为表
a
和trips
表做两次左连:trips.client_id = a1.users_id
trips.driver_id = a2.users_id
因为
trips
作为主体表,和a
表左连,连接的结果是被禁止的用户行程数据而我们要的结果是非禁止用户的形成数据,
a
中users_id
为null
的就是我们要的数据所以最后的筛选条件是
a1.users_id is null and a2.users_id is null
这种写法还可以反过来写,查出没被禁止的用户
a
和trips
做内连,就不会有null
存在The text was updated successfully, but these errors were encountered: