首先见第一个需求如下图所示:
一开始是选用Case When来实现分组(这里按季度分组)显示,如以下测试SQL:
SELECT
(CASE
WHEN (ob_created_time> '2016-01-06 09:51' and ob_created_time < '2016-03-06 09:54') THEN '2016年第1季度'
WHEN (ob_created_time> '2016-07-06 09:51' and ob_created_time < '2016-07-07 09:53') THEN '2016年第2季度'
WHEN (ob_created_time> '2016-07-07 09:59' and ob_created_time < '2016-07-08 09:51') THEN '2016年第3季度'
WHEN (ob_created_time> '2016-09-06 09:51' and ob_created_time < '2016-12-06 09:54') THEN '2016年第4季度'
END) quarter,
COUNT(ob_uuid) userCounts FROM am_object WHERE ob_object_class='User'
GROUP BY quarter;
最后用一个union将不同分组(quarter,year,month)的查询结果链接起来,测试sql如下:
SELECT
(CASE
WHEN (ob_created_time> '2016-01-01 09:51' and ob_created_time < '2016-03-31 09:54') THEN '2016年第1季度'
WHEN (ob_created_time> '2016-04-01 09:51' and ob_created_time < '2016-06-30 09:53') THEN '2016年第2季度'
WHEN (ob_created_time> '2016-07-01 09:59' and ob_created_time < '2016-09-30 09:51') THEN '2016年第3季度'
WHEN (ob_created_time> '2016-10-01 09:51' and ob_created_time < '2016-12-31 09:54') THEN '2016年第4季度'
END) t,COUNT(ob_uuid) userCounts FROM am_object WHERE ob_object_class='User' and 'quarter' like 'quarter' GROUP BY t
UNION
SELECT
(CASE
WHEN (ob_created_time> '2015' and ob_created_time < '2016') THEN '2015年'
WHEN (ob_created_time> '2016' and ob_created_time < '2017') THEN '2016年'
WHEN (ob_created_time> '2017' and ob_created_time < '2018') THEN '2017年'
WHEN (ob_created_time> '2018' and ob_created_time < '2019') THEN '2018年'
END) t,COUNT(ob_uuid) userCounts FROM am_object WHERE ob_object_class='User' and 'year' like 'year' GROUP BY t
UNION
SELECT
(CASE
WHEN (ob_created_time> '2016-01' and ob_created_time < '2016-02') THEN '1月份'
WHEN (ob_created_time> '2016-02' and ob_created_time < '2016-03') THEN '2月份'
WHEN (ob_created_time> '2016-03' and ob_created_time < '2016-04') THEN '3月份'
WHEN (ob_created_time> '2016-04' and ob_created_time < '2016-05') THEN '4月份'
WHEN (ob_created_time> '2016-05' and ob_created_time < '2016-06') THEN '5月份'
WHEN (ob_created_time> '2016-06' and ob_created_time < '2016-07') THEN '6月份'
WHEN (ob_created_time> '2016-07' and ob_created_time < '2016-08') THEN '7月份'
WHEN (ob_created_time> '2016-08' and ob_created_time < '2016-09') THEN '8月份'
WHEN (ob_created_time> '2016-09' and ob_created_time < '2016-10') THEN '9月份'
WHEN (ob_created_time> '2016-10' and ob_created_time < '2016-11') THEN '10月份'
WHEN (ob_created_time> '2016-11' and ob_created_time < '2016-12') THEN '11月份'
WHEN (ob_created_time> '2016-12' and ob_created_time < '2016-12-31') THEN '12月份'
END) t, COUNT(ob_uuid) userCounts FROM am_object WHERE ob_object_class='User' and 'month' like 'month' GROUP BY t;
显示结果如下:
接下来考虑如何将开始日期和结束日期作为一个变量值传入,首先查询出在开始和结束日期间的所有数据,sql如下:
select * from am_object
WHERE ob_object_class='User'
and ob_created_time>='2016'
and ob_created_time<='2017'
然后再将查询出来的结果根据时间进行分组,如下sql:
SELECT
(CASE
WHEN (QUARTER(z.ob_created_time)=1) THEN (CONCAT(YEAR(z.ob_created_time),'年第1季度'))
WHEN (QUARTER(z.ob_created_time)=2) THEN (CONCAT(YEAR(z.ob_created_time),'年第2季度'))
WHEN (QUARTER(z.ob_created_time)=3) THEN (CONCAT(YEAR(z.ob_created_time),'年第3季度'))
WHEN (QUARTER(z.ob_created_time)=4) THEN (CONCAT(YEAR(z.ob_created_time),'年第4季度'))
END) t,COUNT(z.ob_uuid) userCounts FROM
(
select * from am_object
WHERE ob_object_class='User'
and ob_created_time>='2016'
and ob_created_time<='2017'
)z
where 'quarter' like 'quarter' GROUP BY t
显示如下:
整理完sql后如下所示:
SELECT
(CASE
WHEN (QUARTER(z.ob_created_time)=1) THEN (CONCAT(YEAR(z.ob_created_time),'年第1季度'))
WHEN (QUARTER(z.ob_created_time)=2) THEN (CONCAT(YEAR(z.ob_created_time),'年第2季度'))
WHEN (QUARTER(z.ob_created_time)=3) THEN (CONCAT(YEAR(z.ob_created_time),'年第3季度'))
WHEN (QUARTER(z.ob_created_time)=4) THEN (CONCAT(YEAR(z.ob_created_time),'年第4季度'))
END) t,COUNT(z.ob_uuid) userCounts FROM
(
select * from am_object
WHERE ob_object_class='User'
and ob_created_time>='2016'
and ob_created_time<='2017'
)z
where 'quarter' like 'quarter' GROUP BY t
UNION
SELECT
(CASE
WHEN (YEAR(z.ob_created_time)=2014) THEN '2014年'
WHEN (YEAR(z.ob_created_time)=2015) THEN '2015年'
WHEN (YEAR(z.ob_created_time)=2016) THEN '2016年'
WHEN (YEAR(z.ob_created_time)=2017) THEN '2017年'
END) t,COUNT(z.ob_uuid) userCounts FROM
(
select * from am_object
WHERE ob_object_class='User'
and ob_created_time>='2016'
and ob_created_time<='2017'
)z
where 'year' like 'year' GROUP BY t
UNION
SELECT
(CASE
WHEN (MONTH(z.ob_created_time)=1) THEN '1月'
WHEN (MONTH(z.ob_created_time)=2) THEN '2月'
WHEN (MONTH(z.ob_created_time)=3) THEN '3月'
WHEN (MONTH(z.ob_created_time)=4) THEN '4月'
WHEN (MONTH(z.ob_created_time)=5) THEN '5月'
WHEN (MONTH(z.ob_created_time)=6) THEN '6月'
WHEN (MONTH(z.ob_created_time)=7) THEN '7月'
WHEN (MONTH(z.ob_created_time)=8) THEN '8月'
WHEN (MONTH(z.ob_created_time)=9) THEN '9月'
WHEN (MONTH(z.ob_created_time)=10) THEN '10月'
WHEN (MONTH(z.ob_created_time)=11) THEN '11月'
WHEN (MONTH(z.ob_created_time)=12) THEN '12月'
END) t,COUNT(z.ob_uuid) userCounts FROM
(
select * from am_object
WHERE ob_object_class='User'
and ob_created_time>='2016'
and ob_created_time<='2017'
)z
where 'month' like 'month' GROUP BY t
这里考虑把
and ob_created_time>='2016'
and ob_created_time<='2017'
作为时间变量($P{startDateKey},$P{endDateKey})传入,同时把季度('quarter' like 'quarter')也作为变量值($P{timeGroup})传入,修改后的sql如下:
select
(CASE
WHEN (QUARTER(z.ob_created_time)=1) THEN (CONCAT(YEAR(z.ob_created_time),'年第1季度'))
WHEN (QUARTER(z.ob_created_time)=2) THEN (CONCAT(YEAR(z.ob_created_time),'年第2季度'))
WHEN (QUARTER(z.ob_created_time)=3) THEN (CONCAT(YEAR(z.ob_created_time),'年第3季度'))
WHEN (QUARTER(z.ob_created_time)=4) THEN (CONCAT(YEAR(z.ob_created_time),'年第4季度'))
END) t,COUNT(z.ob_uuid) userCounts FROM
( select * from am_object
WHERE ob_object_class='User'
and ob_created_time>=$P{startDateKey}
and ob_created_time<=$P{endDateKey}
)a
where "quarter" like $P{timeGroup} group by t
后来,为了简化sql,将case when替换掉,修改sql后为:
select
CONCAT(YEAR(a.ob_created_time),'年',QUARTER(a.ob_created_time),'季度') t,COUNT(a.ob_uuid) userCounts
from
( select * from am_object
WHERE ob_object_class='User'
and ob_created_time>=$P{startDateKey}
and ob_created_time<=$P{endDateKey}
)a
where "quarter" like $P{timeGroup} group by t
是不是很简洁啦?至此,sql已经写好,接下来需要在ireport下创建相应变量parameter,如下
其中,startDateKey作为模糊查询变量设置如下
另外为了计算所有userCounts,添加了total变量,其设置如下
接着导入sql后,需另外创建field变量
接着将创建的t,userCounts变量拖动到报表detail中,如下:
做好这些后,接着就是为
$P{startDateKey},
$P{endDateKey},
$P{timeGroup}创建传入什么值了,登陆到JasperServer上面,进入userCount
编辑页面,添加相应的开始时间,结束时间和时间分组,如下
其中已开始时间为例,点击“添加输入控制”后,进入
直接点击下一步,一步步跟着提示走
注意这里的变量要跟你写的SQL 中的($P{startDateKey})命名相对应。接着创建时间分组:
注意:这里的值(quarter,year,month,week)是指传入你写的sql中
$P{timeGroup}的对应字符串值。
至此创建完毕,记得点击提交,最后查看效果
至此感觉应该全部好了,其实不然,当你点击时间后,发现传入sql中
$P{startDateKey}的时间格式为“月日年 时分”,而我本地数据库中的
ob_created_time字段值
时间格式为“年月日 时分秒”,
为此,我重新修改了sql,修改后的sql如下:
select
CONCAT(YEAR(a.ob_created_time),'年',QUARTER(a.ob_created_time),'季度') t,COUNT(a.ob_uuid) userCounts
from
( select * from am_object
WHERE ob_object_class='User'
and ob_created_time>=concat(substring($P{startDateKey},7,4),'-',substring_index($P{startDateKey},'- ',2),substring($P{startDateKey},11,6))
and ob_created_time<=concat(substring($P{endDateKey},7,4),'-',substring_index($P{endDateKey},'-',2),substring($P{endDateKey},11,6))
)a
where "quarter" like $P{timeGroup} group by t
union
select
CONCAT(YEAR(a.ob_created_time),'年') t,COUNT(a.ob_uuid) userCounts
from
(select * from am_object
WHERE ob_object_class='User'
and ob_created_time>=concat(substring($P{startDateKey},7,4),'-',substring_index($P{startDateKey},'-',2),substring($P{startDateKey},11,6))
and ob_created_time<=concat(substring($P{endDateKey},7,4),'-',substring_index($P{endDateKey},'-',2),substring($P{endDateKey},11,6))
)a
where "year" like $P{timeGroup} group by t
union
select
CONCAT(YEAR(a.ob_created_time),'年',MONTH(a.ob_created_time),'月') t,COUNT(a.ob_uuid) userCounts
from
(select * from am_object
WHERE ob_object_class='User'
and ob_created_time>=concat(substring($P{startDateKey},7,4),'-',substring_index($P{startDateKey},'-',2),substring($P{startDateKey},11,6))
and ob_created_time<=concat(substring($P{endDateKey},7,4),'-',substring_index($P{endDateKey},'-',2),substring($P{endDateKey},11,6))
)a
where "month" like $P{timeGroup} group by t
union
select
CONCAT(YEAR(a.ob_created_time),'年第',WEEK(a.ob_created_time),'周') t,COUNT(a.ob_uuid) userCounts
from
(select * from am_object
WHERE ob_object_class='User'
and ob_created_time>=concat(substring($P{startDateKey},7,4),'-',substring_index($P{startDateKey},'-',2),substring($P{startDateKey},11,6))
and ob_created_time<=concat(substring($P{endDateKey},7,4),'-',substring_index($P{endDateKey},'-',2),substring($P{endDateKey},11,6))
)a
where "week" like $P{timeGroup} group by t
这里用到了MySQL中的
substring()和
substring_index()两个函数,把传入的时间格式进行强制性转化,最后查询效果图如下