题目描述:sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的订单信息,并且按照order_info的id升序排序。
个人思路:与(二)几乎一样。不过的是因为要显示的所有信息因此不能直接使用group by后的结果。
方法一:内表找出user_id,外表找出该user_id符合的记录。
with moreThan1 as ( select user_id from order_info where datediff(date,"2025-10-15")>0 and product_name in ("C++","Java","Python") and status ="completed" group by user_id having count(id)>1 ) select * from order_info where datediff(date,"2025-10-15")>0 and product_name in ("C++","Java","Python") and status="completed" and user_id in (select * from moreThan1) order by id;
或者这么写
select * from order_info where datediff(date,"2025-10-15")>0 and product_name in ("C++","Java","Python") and status="completed" and user_id in ( select user_id from order_info where datediff(date,"2025-10-15")>0 and product_name in ("C++","Java","Python") and status ="completed" group by user_id having count(id)>1 ) order by id;
方法二:窗口函数
select t1.id, t1.user_id,t1.product_name,t1.status,t1.client_id,t1.date from ( select *,count(id) over(partition by user_id) as number from order_info where datediff(date,"2025-10-15")>0 and status ="completed" and product_name in ("C++","Java","Python") ) t1 where t1.number >1 order by t1.id
用count()作为窗口函数来检索以user_id分组的行数并作为临时表的新列。然后对临时表按题目要求依次添加筛选条件。关于为什么t1.number要放在外表where后进行判断。因为count()属于聚合函数在临时表t1里无法放在where后进行判断。但是在外表number是一个列的字段名,其值可以直接拿来进行判断。但更主要的原因还是mysql的执行顺序:开始->from子句->where子句->group by子句->having子句->select子句->最终结果。