第一题,如下图是一张简单的消费记录表,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