`
aa87963014
  • 浏览: 154453 次
  • 性别: Icon_minigender_1
  • 来自: 布尼塔尼亚
社区版块
存档分类
最新评论

让报表完蛋去,超简单的方法完成任务

 
阅读更多

代价总是会有的,不是开发快就是效率低。如果你在收到类似于这类任务

 

 

本页显示所有等级段内的人数

等级

h府

g房

f场

e场

d场

c营

b营

a营

i馆

j院

k仓

l仓

m集

1-10

 

 

 

 

 

 

 

 

 

 

 

 

 

10-20

 

 

 

 

 

 

 

 

 

 

 

 

 

20-30

 

 

 

 

 

 

 

 

 

 

 

 

 

30-40

 

 

 

 

 

 

 

 

 

 

 

 

 

5

 

 

 

 

 

 

 

 

 

 

 

 

 

6

 

 

 

 

 

 

 

 

 

 

 

 

 

7

 

 

 

 

 

 

 

 

 

 

 

 

 

8

 

 

 

 

 

 

 

 

 

 

 

 

 

9

 

 

 

 

 

 

 

 

 

 

 

 

 

10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

100

 

 

 

 

 

 

 

 

 

 

 

 

 

 

表结构:

{

id

level

buildid (建筑类型)

uid

}

 

在我想到这个点子的时候不是为了解决上面这个查询,而是为了解决一堆这样的查询。

本来是以为用一些表达式来做,但是实际上我发现按照如下的方法更直观,没有任何学习成本。

如果你发现结果和你预想的不同。那么久断点下,看看生成的sql是否是正确的。这里有一个拼接sql字符串的东西。

 

 

当你还在想破脑筋为了这些无聊的东西发愁的时候,有这么一小段代码帮你偷工减料。

 

1、构造一个Result对象

 

public class Result {
	public List<String[]> select = new ArrayList<String[]>();
	public List<String> where = new ArrayList<String>();
	public List<String[]> group = new ArrayList<String[]>();
	public List<String> order = new ArrayList<String>();
}

 

 

2、Result result = new Result();

		result.select.add(new String[] { "府",
				"select count(*) from Building where buildid = 4 and ?" });
		result.select.add(new String[] { "房",
				"select count(*) from Building where buildid = 10 and ?" });
		result.select.add(new String[] { "场",
				"select count(*) from Building where buildid = 1 and ?" });
		result.select.add(new String[] { "场",
				"select count(*) from Building where buildid = 2 and ?" });
		result.select.add(new String[] { "场",
				"select count(*) from Building where buildid = 3 and ?" });
		result.select.add(new String[] { " 兵",
				"select count(*) from Building where buildid = 5 and ?" });
		result.select.add(new String[] { "兵",
				"select count(*) from Building where buildid = 6 and ?" });
		result.select.add(new String[] { "兵",
				"select count(*) from Building where buildid = 7 and ?" });
		result.select.add(new String[] { "馆",
				"select count(*) from Building where buildid = 12 and ?" });
		result.select.add(new String[] { "院",
				"select count(*) from Building where buildid = 11 and ?" });
		result.select.add(new String[] { "仓",
				"select count(*) from Building where buildid = 8 and ?" });
		result.select.add(new String[] { "仓",
				"select count(*) from Building where buildid = 9 and ?" });
		result.select.add(new String[] { "集",
				"select count(*) from Building where buildid = 13 and ?" });

		result.group.add(new String[] { "1", "level >=1 and level < 10" });
		result.group.add(new String[] { "2", "level >=10 and level < 20" });
		result.group.add(new String[] { "3", "level >=20 and level < 30" });
		result.group.add(new String[] { "4", "level >=30 and level < 40" });
		result.group.add(new String[] { "5", "level >=40 and level < 50" });
		result.group.add(new String[] { "6", "level >=50 and level < 60" });
		result.group.add(new String[] { "7", "level >=60 and level < 70" });
		result.group.add(new String[] { "8", "level >=70 and level < 80" });
		result.group.add(new String[] { "9", "level >=80 and level < 90" });
		result.group.add(new String[] { "10", "level >=90 and level < 100" });

		List<User> users = playerMng.findByHql("from User where name = '"
				+ userName + "'");

		if (users.size() != 0) {
			result.where.add("userId = " + users.get(0).getUid());
		}

 3、select!

 

public List parserHQL(Result result) {
		List list = new ArrayList();
		for (String[] garr : result.group) {
			// Map map = new HashMap();
			Object[] arr = new Object[result.select.size() + 1];
			int i = 1;
			arr[0] = garr[0];
			for (String[] sarr : result.select) {
				Object obj = null;

				String sql = sarr[1].replace("?", garr[1]);

				String groupSql = "";
				if (sql.indexOf("#") != -1) {
					groupSql = sql.split("#")[1];
					sql = sql.split("#")[0];
				}
				for (String where : result.where) {
					sql += " and " + where;
				}
				sql += groupSql;
				List l = dao.findByHql(sql);
				if (l != null && l.size() > 0) {
					obj = l.get(0);
				}
				// map.put(sarr[0], obj);
				arr[i] = obj;
				i++;
			}
			list.add(arr);
		}
		return list;
	}

 

 

构造Result 对象的时候别看字多,逻辑非常简单。不用去想什么sql怎么写。

 

groop list保存的是Y轴条件,

where list 保存的是总条件。如查询uid为xxx的 这个报表

select list 保存的是显示内容和查询sql(主)

 

数组第0个元素为显示内容,第一个元素为sql的条件。 这个条件会替换掉X轴sql里面的 ? 

 

如果X轴是带GROUP的sql  并且还有总条件那么需要用#代替。

 

如果想order一下,这个功能还没加。不过也就是根据最终的list 排序而已。

 

如果想分页?我觉得这类查询不需要分页。

 

如果想优化性能?当然可以,毫无疑问虽然写了那么多。实际上一个结果集中大概80%的查询内容是可以从同一个sql结果集中取出结果。每合并一个查询结果会减少Y轴数量 个查询 ~

 

------------

这里只是抛砖引玉,只适合存在Y轴条件的查询。如果你优化的足够好,就像上面说的那样合并查询内容。实际上和你去捣鼓sql的效果一样。一般是不需要分页的,排序更不是问题。

 

原理就是 Y轴条件+X轴条件 一定是单一值,然后写个程序循环下 再把结果拼起来。

 

---再贴几个实现。

 

 

 本页显示对应等级的数量,以及拥有对应等级的人数 

等级

数量

人数

一级

 

 

二级

 

 

三级

 

 

四级

 

 

五级

 

 

六级

 

 

七级

 

 

八级

 

 

九级

 

 

 

 

		Result result = new Result();
		result.select.add(new String[] { "数量",
				"select count(*) from t_treasure where  ?" });	
		
		result.select.add(new String[] { "人数",
		"select count(*) from (select count(*) from t_treasure where  ? # group by user_Id) a" });	
		
		result.group.add(new String[] { "一级", "strong_Level = 1" });
		result.group.add(new String[] { "二级", "strong_Level = 2" });
		result.group.add(new String[] { "三级", "strong_Level = 3" });
		result.group.add(new String[] { "四级", "strong_Level = 4" });
		result.group.add(new String[] { "五级", "strong_Level = 5" });
		result.group.add(new String[] { "六级", "strong_Level = 6" });
		result.group.add(new String[] { "七级", "strong_Level = 7" });
		result.group.add(new String[] { "八级", "strong_Level = 8" });
		result.group.add(new String[] { "九级", "strong_Level = 9" });

 

----------

 

再更新一个。。。这个本来不想用这种方法的。。但是突然开始头痛。。。分页方式示例。让分页、排序也成浮云。

 

 

		Result result = new Result();
		result.select
				.add(new String[] { "金额",
						"select sum(num)/10 from t_gold_record where type = '53' and ?" });

		result.select
				.add(new String[] { "总数",
						"select sum(num)/10 from t_gold_record where type in('47','58','59') and ?" });

		result.select
				.add(new String[] {
						"未消耗数",
						"select sum(num)/10 from t_gold_record where type not in('47','58','59','53') and ?" });

		Pagination pagination2 = mallMng
				.findBySql(
						"select date_format(record_time, '%Y-%m') from t_gold_record  group by date_format(record_time, '%Y-%m') desc",
						pageNo, getCookieCount());

		for (Object obj : pagination2.getList()) {

			result.group.add(new String[] { obj.toString(),
					"date_format(record_time, '%Y-%m') = '" + obj + "'" });
		}

		List list = mallMng.parserSQL(result);

 

  vf

 

表结构

{

id

type

num

uid

record_time

}

 

这次呢,没有Y轴了,表面上看起来没有Y轴 实际上Y轴大家心里都知道了。就是record_time 的月份 Y轴由一段查询结果构成,因为这段结果是分页的,相当于整个报表也是分页的!同时Y轴排序=对整个报表排序。

 

 

 

 

3
3
分享到:
评论
5 楼 vtrtbb 2011-12-21  
case when + sum 就可以搞定,没有这么麻烦

4 楼 houxinyou 2011-12-21  
把我看蒙了,根本没看懂!
3 楼 jackra 2011-12-20  
确实是个好办法。
在不考虑效率的前提下。
2 楼 a545807638 2011-12-20  
看错了,呵呵,一个sql通用性的话就不行了
1 楼 a545807638 2011-12-20  
case when,加分组统计函数,搞定,一个sql

相关推荐

Global site tag (gtag.js) - Google Analytics