所写 sql的背景:对应一个统计的业务,对应两张表中的数据,需求是:在页面上展示的内容为第一列名称对应行政区划的所有记录并以树的形式展示,其他列的数据则对应杂志征订信息表中的记录,如果杂志征订信息表中有数据则在相应的地区那行显示出来,没有则对应的那行数据补0,并且要求如果杂志征订信息表中有相同的地区记录,那么其他的字段要求和,然后合并为一条记录。
id:sql 的标记,代码中通过id的值找到相应的sql语句
parameterClass :参数的数据类型
resultClass:返回结果的数据类型
<select id="selectByConnection"parameterClass="com.itic.zzzd.zdxxgl.persistence.model.SelectCondition" resultClass="com.itic.zzzd.zdxxgl.persistence.model.QktjVO">
select x.dm,x.sjdm,
x.mc,
decode(zt.scTotal, null, '0',zt.scTotal) scTotal,
decode(zt.xcTotal, null, '0', zt.xcTotal) xcTotal,
decode(zt.qkjeTotal, null, '0', zt.qkjeTotal) qkjeTotal,
decode(zt.ssjeTotal, null, '0', zt.ssjeTotal) ssjeTotal,
decode(zt.hjTotal, null, '0', zt.hjTotal) hjTotal,
decode(zt.qkConcat,null,'',zt.qkConcat) qkConcat
from t_dm_xzqh x
left join (select t.qhdm ztqhdm,
WMSYS.WM_CONCAT(t.qkyy) qkConcat,
sum(t.sc) scTotal,
sum(t.xc) xcTotal,
sum(t.qkje) qkjeTotal,
sum(t.ssje) ssjeTotal,
sum(t.hj) hjTotal
from (select z.*,
(case
when z.country is not null then
z.country
when z.city is not null then
z.city
else
z.province
end) qhdm
from t_zd_zdxxgl z
where z.scbj = '0' and z.zdfs <> '2'
<dynamic>
<isNotEmpty prepend="AND"property="nf">
Z.NF = #nf:VARCHAR#
</isNotEmpty>
<isNotEmpty prepend="AND"property="lrsjStar">
TO_CHAR(Z.LRSJ,'YYYY-MM-DD HH24:MI:SS') >= TO_CHAR(#lrsjStar:TIMESTAMP#,'YYYY-MM-DD HH24:MI:SS')
</isNotEmpty>
<isNotEmpty prepend="AND"property="lrsjEnd">
TO_CHAR(Z.LRSJ,'YYYY-MM-DD HH24:MI:SS') <= TO_CHAR(#lrsjEnd:TIMESTAMP#,'YYYY-MM-DD HH24:MI:SS')
</isNotEmpty>
</dynamic>
) t
where t.scbj='0'
group by t.qhdm) zt
on x.dm = zt.ztqhdm
where x.scbj = '0'
<dynamic>
<isNotEmpty property="qhdm">
start with x.dm = #qhdm:VARCHAR# connect by prior x.dm = x.sjdm
</isNotEmpty>
</dynamic>
</select>
解释 :
1. decode(zt.scTotal, null, '0',zt.scTotal) scTotal:decode函数:if(zt.scTotal==null){ return '0'}else{return zt.scTotal} 给该字段去了个别名scTotal; 和case when 的效果一样;
2. 表1 left join 表2 on 关联的列:表一通过关联条件左联接表二,结果是表一的数据全部显示,表二的数据只显示符合条件的;
3. WMSYS.WM_CONCAT(t.qkyy) qkConcat :Oracle中分组函数查询的数据只能是用以分组的字段和聚合函数,其他的不可以,这个是分组后将不同记录的字符串合并,具体什么原因不清楚
4. ibatis中查询语句放在where后面就可以,不必做什么特殊处理,如 <dynamic>
<isNotEmpty prepend="AND"property="nf">
Z.NF = #nf:VARCHAR#
</isNotEmpty> ,
<isNotEmpty prepend="AND"property="lrsjStar">
TO_CHAR(Z.LRSJ,'YYYY-MM-DD HH24:MI:SS') >= TO_CHAR(#lrsjStar:TIMESTAMP#,'YYYY-MM-DD HH24:MI:SS')
</isNotEmpty>
<isNotEmpty prepend="AND"property="lrsjEnd">
TO_CHAR(Z.LRSJ,'YYYY-MM-DD HH24:MI:SS') <= TO_CHAR(#lrsjEnd:TIMESTAMP#,'YYYY-MM-DD HH24:MI:SS')
</isNotEmpty>
</dynamic>
的位置 ,另外ibatis中大于号用 > 表示,小于号用 < 表示,数据库中的数据类型如果是timestamp类型的在ibatis中要用MI表示 ;
5. start with 条件1 connect by prior 条件2 此句为树形结构的查询语句:
条件1 是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。
条件2 是连接条件,其中用PRIOR表示上一条记录,比如 CONNECT BY PRIOR org_id = parent_id;就是说上一条记录的 org_id 是本条记录的parent_id,即本记录的父亲是上一条记录。