1.拼多多面试题sql(来自牛客)
自连接的思路 t1 join t2 on t1.ip=t2.ip where t1.uid != t2.uid group by t1.uid, t2.uid having count(*)>=3,但是这样自连接不会出现id1,id2和id2,id1这样反序的重复情况,所以我就改成log1.uid
select log1.uid,log2.uid
from ip_log log1 inner join ip_log log2 on log1.ip=log2.ip and log1.uid group by log1.uid,log2.uid having count(*)>=3 建一个表看看,方便理解: truncate table ip_log; insert into ip_log values('a' , '124' , '2019-08-07'); insert into ip_log values('b' , '124' , '2019-08-07'); insert into ip_log values('c' , '124' , '2019-08-07'); insert into ip_log values('a' , '174' , '2019-08-07'); insert into ip_log values('b' , '174' , '2019-08-07'); insert into ip_log values('a' , '194' , '2019-08-07'); insert into ip_log values('b' , '124' , '2019-08-07'); 2. order(ord_id,mall_id,goods_id,sale_number,amount),求每个商店里的商品价格的中位数。 (用到了开窗函数和join,我大体方向正确,但是考虑不周全,面试官有引导纠正) 我觉得下面这类似的求的不是特别好 应该用 rank over 开窗排序 select * from (SELECT id,name, Sales,rank() over (partition by id order by Sales) rank_ FROM median_sale)a inner join (select id,count(*) as cnt from median_sale group by 1 )b on a.id=b.id where a.rank_=(b.cnt+1) div 2 增加考虑奇偶,如果是偶数保留中间两个,最后求平均 select a.id,avg(Sales) as median from (SELECT id,name, Sales,rank() over (partition by id order by Sales) rank_ FROM median_sale)a inner join (select id,count(*) as cnt from median_sale group by 1 )b on a.id=b.id where case when b.cnt%2 !=0 then a.rank_=((b.cnt+1) div 2) else (a.rank_= (b.cnt) div 2 or (a.rank_= b.cnt div 2 +1) )end group by 1 中间步骤是这样的 WHERE tab.sales_rank=(select (count(*)+1) div 2 from total_sales); SELECT * from ( SELECT a1.Name, a1.Sales, COUNT(a2.sales) Sales_Rank FROM Total_Sales a1, Total_Sales a2 WHERE a1.Sales < a2.Sales or (a1.Sales=a2.Sales and a1.Name = a2.Name) GROUP BY a1.Name, a1.Sales ORDER BY a1.Sales DESC, a1.Name DESC ) as tab WHERE tab.sales_rank=(select (count(*)+1) div 2 from total_sales); 可以查找到中间的项,count(*)+1,这个1必须要添加,总项数假如为奇数7,则count(*)+1 / 2 = 4,假如是6则为3,都是满足的,如果不+1的话,对奇数项则不满足,如7,count(*) /2 = 3,而我们要查找的则是位于4的位置 滴滴sql一 image.png 两个表如上,查出每个司机每天接的第一单(name,o_id); 方法一 image.png 方法二 image.png 存在问题:没有接单的用户不存在了 可以改进使用左连接和右连接 作者:微斯人_吾谁与归 链接:https://www.jianshu.com/p/eb4d8404ec12 来源: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 insert into t1 values('1','c罗','33'); insert into t1 values('2','梅西','31'); insert into t1 values('3','内马尔','29'); insert into t2 values('1','3','1'); insert into t2 values('1','5','2'); insert into t2 values('2','0','1'); insert into t2 values('2','8','2'); 很多同学在学习 Mysql 表关联的时候弄不清ON与WHERE的区别,不知道条件应该写在ON里面还是WHERE里面,作者在工作的时候也入过坑,总觉得条件写在哪里查询结果都是一样的,最后出错坏了事,差点惹了大祸。所以今天简单易懂的总结一下他们的区别,大家共同学习。 准备工作 我们先准备两个表,并造一些数据: -- t1createtablet1(idbigintdefault'0'notnullcomment'主键id',namechar(100)default''notnullcomment'姓名',ageintdefault'0'notnull);-- t2createtablet2(idbigintdefault'0'notnullcomment'主键id',goalsintdefault'0'notnullcomment'进球数',matchesintdefault'0'notnullcomment'比赛编号'); t1, t2 探究 口诀:先执行ON,后执行WHERE;ON是建立关联关系,WHERE是对关联关系的筛选。记住这句话就可以准确地判断查询结果了,我们通过两个 sql 来进行分析: SELECTt1.id,t1.name,t1.ageFROMt1LEFTJOINt2ONt1.id=t2.idWHEREmatches=2;-- 条件放在 WHERESELECTt1.id,t1.name,t1.ageFROMt1LEFTJOINt2ONt1.id=t2.idANDmatches=2;-- 条件放在 ON 执行第一个 sql 时,前提是LEFT JOIN,所以左边的数据在创建关联关系时会保留,根据口诀,先执行ON建立关联关系,然后通过WHERE筛选,过程如下: sql1 第二个 sql 没有WHERE,那么ON建立的关联关系就是最终结果: sql2 通过这两个 sql 可以很好的区分WHERE和ON的区别了,希望大家使用的时候多注意这一点,避免犯错! 作者 小菜荔枝原创 转载请联系作者获得授 作者:小菜荔枝 链接:https://www.jianshu.com/p/d923cf8ae25f 来源: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 在使用left join时,on and和 where and条件的区别如下: 在使用链接时,先执行 on and,再执行 where and 1. on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左表中的记录。 2. where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录了), 条件不为真的就全部过滤,on后的条件用来生成左右表关联的临时表,where后的条件对临时表中的记录进行过滤。 在使用inner join时,on and和 where and条件: 取交集,on and后对左右表都筛选,和where一样。 具体数据比较看原链接: http://blog.csdn.net/xingzhemoluo/article/details/39677891