考几道小有难度的sql语句

第一题,如下图是一张简单的消费记录表,mid表示用户id,product_id代表商品id,ymd为消费时间。通过以下表,请查询出仅购买过产品id为23的用户。比如说mid为2的用户虽然有过产品为23的记录,但是也有其它产品的记录。所以是不符合条件。

 

解答:这道题还算简单,思路就是排除购买过其它产品并购买过23产品的记录。举例列出两个方法。

方法1:select distinct(mid) from morder where product_id=23 and id not in (select id from morder where product_id <>23)

方法2: select  distinct(mid) from morder where product_id not in (select product_id from morder where product_id<>23)

第二题:如下图是一张用户表,nickname表示昵称,username表示用户名。用户名是唯一的,昵称可以不唯一。现在的需求是查找出所有有重复昵称的用户名,比如hw01和hw02都是用的小明为昵称就要查找出来。

 

解答:一般听到查找重复或不重复就会第一时间想到group by,其实这道题用分组是比较困难,而简单的方法是联表。下面分别以分组和联表写出方法。

方法1:select  username from member where nickname in (select nickname from morder group by nickname having count(id)>1)

方法2:select a.username from member a,member b where a.id<>b.id and a.nickname=b.nickname

第三题,这道题有些难度了。下图是一张呼叫记录表call_log,其中from为呼出,to为呼入,ymd为通话开始时间。因为呼出和呼入是对等的,所以现在要统计出多少组对话,比如说112打给233和233和112是统计为一组对话的。

 

解答:说到查询重复或去除重复还是会想到分组,而这道题不论是分组还是联表都是很难实现的。解题的思路是先把呼出和呼叫按照一定顺序整理,然后再去重查找。

方法: select  if(`from`>to,to:`from`) as a,if(`from`>to,`from`:to) b from call_log  group by a,b

原文地址:https://www.cnblogs.com/zuoshoupai/p/7231744.html