问题背景:
在做APP的嵌入页面的时候,部长给提了这么一个需求,需要从生产信息的视图中查询出每种产品中已经成熟的一条信息,为了更好的显示效果。简单的说,就是黄瓜和茄子分别被种植在1号大棚和2号大棚里,这样就会产生4条种植信息,我们想要的结果是按照产品名称检索每个产品名称下的任意一条种植信息即可。比如,黄瓜的种植信息有两条,随便拿出来一条,茄子亦如此,那么我们想要的结果就是两条(不指定是哪两条,随意)。
问题分析:
刚开始我想到的办法是,通过编写SQL语句实现,于是就在SQL Server中开始试验
首先将所有符合情况的记录查询出来
<span style="font-size:18px;"> select * from dbo.sn_plant_product_view where catename ='加工类' andnowplant =0 and harveststate =1</span>
然后再使用group by子句将不重复的产品名称查询出来,
<span style="font-size:18px;">select pdtname from dbo.sn_plant_product_view where catename='加工类' and nowplant =0 and harveststate =1 group by pdtname</span>
最后在进行组合查询的时候,发现使用拼接SQL语句的方式行不通,无论我怎样写,返回的都是全部的结果,原因是什么呢?原因就是group by只能将数据进行分组操作,但是无法完成在每组中取一条记录的操作,换句话说,使用SQL语句,只能进行分组操作,不能为你完成在每一组数据中任取一条记录的工作。当然我们可以对group by分组结果进行统计和计算,比如统计每组数据的条数等等。
至于我想要的效果只能通过写算法实现了,于是开始思考如何写程序来实现。其实只要对上述的两个结果进行比较筛选,即可得到想要的结果。
问题解决:
经过简单的分析,之后,便将方法写完了,测试了一下可以解决问题,代码如下:
public List<SnPlantProductView> listForApp(String catename){
//1.首先将结果集中不重复的产品名称查询出来
String hql ="select pdtname from SnPlantProductView where catename= ? and nowplant=0 and harveststate=1 group by pdtname";
List<String> listName=super.listByHql(hql, catename);
//2.将符合查询条件的所有记录查询出来
Finder finder = Finder.create("from SnPlantProductView ");
finder.append(" where catename =:catename and nowplant=0 and harveststate = 1");
finder.setParam("catename", catename);
List<SnPlantProductView> list = listByFinder(finder);
//3.声明一个实体LIst集合变量,用于存放不重复的结果记录
List<SnPlantProductView> resultList=new ArrayList<SnPlantProductView>();
//4.使用两重for循环将结果集中任意一条匹配listName集合中的名称的记录拿出来,放入resultList集合中
for(int i=0;i< listName.size();i++){
for(int j=0;j<list.size();j++){
/*
* 只要list集合中有记录的产品名称和listName集合中的名称匹配,
* 就将这条记录放入resultList中,并且跳出当前循环,取下一个名称进行匹配
* 直到遍历所有的名称,这时候,resultList中的记录数和listName中的记录数
* 是一样的,这样就达到了去重复的目的
*/
if(listName.get(i).equals(list.get(j).getPdtname())){
resultList.add(list.get(j));
break;
}
}
}
return resultList;
}
小结一下:
其实我的办法还是有缺陷的,如果数据量非常的大,会出现性能瓶颈,两重For循环,在大数据量的情况下,会消耗很长的时间,进行匹配,最终才能返回结果,速度上就会大打折扣。我知道还有其他的办法,只是我还想不出来,如果大神们有什么更好的解决方案,请不吝赐教。