select sum(s.cjl) cjl1, sum(s.ysje) ysje1 ,w2.mc mc
from s_lf s, j_pbxx p, c_zzcc z, j_yhda y,
j_bda b, c_dwlcc w, d_yhlb yhlb, c_dwlcc w2
where s.id = b.id
and z.id = p.pzwz
and z.wlccid = w.id
and p.id = s.id
and y.id = s.yhid
and w2.qxm like '100101__'
and w.qxm like w2.qxm||'%'
-- and yhlb.id = 'd01'
-- and s.yf = '201412'
and yhlb.id = p.yhlb group by w2.mc
这是同事问我时候我写出来的sql .之前的博文中应该谈到过关于层次的查询. 很有技巧性
谈这个sql首先要谈全息码. 什么是全息码: 比如这样的组织层次. 比如某县教育局用的. 最顶层的组织层次是一个元素.就是教育局.比如是01 .次级是地区吧,就是从0101开始编码(可以根据元素多少选择每一级的位数 这个可以是十六进制 不过二百多应该够了,元素再多也不适合在层次中, 不适合用层次处理). 再次是是学校. 比如东区是0101. 那东区第一个学校是010101. 再下是校长, 然后 ..然后.. 每个任职的人员都有对应的全息码. 有了它非常利于管理
ok.目的: 这个sql是要找100101下的
各第一级子节点下的抄见量应收金额的和.
技巧: 这里有w 和w2都是电网络层次 w2 是为了限定w . 先定好w2 w2 是100101下的
第一级子节点. 之后限制w .w是w2的
所有子节点 最后groupby w2 这样就得到了w2 的每个节点的 结果
select sum(qfje) from (
select sum(qf.qfje) qfje,yh.id from
s_qf qf, j_pbxx_history pb,
c_dwlcc_history wlcc, j_yhda_history yh
where
qf.yhid = pb.yhid
and pb.yhid = yh.id
and yh.yhzl = '居民'
and pb.pzwz = wlcc.id
-- and wlcc.id = zzcc.wlccid
and pb.yf = wlcc.yf
and yh.yf = pb.yf
and pb.yf = qf.yf
-- and qf.yf = '201411'
-- and wlcc.yf = zzcc.yf
-- and zzcc.yf = yh.yf
and wlcc.qxm like '10010101%'
-- and yh.id = 'd01010000000007'
group by yh.id
)
总计一下欠费.某个节点下所有用户的欠费.
不难,要说的是灵活的用groupby. 我之前不太会groupby. 或者会但不能灵活应用.
欠费这个东西有点特别 没有历史表(原因是他没有当月表, 当月还没收完费呢哪来的欠费).所以欠费表里是所有月份的,查这个表每个用户的累计欠费就要groupby用户id 得到每个用户id 的 sum(xx) 要得到这个地区总的欠费.最外层简单的加个sum就行了
select sum(bl)
from ((select lb.id, lb.mc, dyhlf.dyhid, sum(lf.ysje) bl
from j_yhda_history yh, j_dyhxxxx_history dyhxx,
s_dyhlf_history dyhlf, j_pbxx_history pb,
d_yhlb_history lb, s_lf_history lf,
c_dwlcc_history wlcc, c_zzcc_history zzcc
where yh.id = dyhxx.id
and dyhxx.dpcid = dyhlf.dyhid
and yh.id = pb.yhid
and pb.yhlb = lb.id
and pb.id = lf.id
and pb.pzwz = wlcc.id
and wlcc.id = zzcc.wlccid
and yh.yf = dyhxx.yf
and dyhxx.yf = dyhlf.yf
and dyhlf.yf = pb.yf
and pb.yf = lb.yf
and pb.yf = lf.yf
and lf.yf = wlcc.yf
and wlcc.yf = zzcc.yf
and wlcc.qxm like '1001%'
and dyhlf.dpyf = '201412'
group by lb.id, lb.mc, lb.zxdj, dyhlf.dyhid)
union all
(select lb.id, lb.mc, dyhlf.dyhid, sum(lf.sjbl) * lb.zxdj bl
from j_yhda yh, j_dyhxxxx dyhxx, s_dyhlf dyhlf, j_pbxx pb,
d_yhlb lb, s_lf lf, c_dwlcc wlcc, c_zzcc zzcc
where yh.id = dyhxx.id
and dyhxx.dpcid = dyhlf.dyhid
and yh.id = pb.yhid
and pb.yhlb = lb.id
and pb.id = lf.id
and pb.pzwz = wlcc.id
and wlcc.id = zzcc.wlccid
and yh.yf = dyhxx.yf
and dyhxx.yf = dyhlf.yf
and dyhlf.yf = pb.yf
and pb.yf = lb.yf
and pb.yf = lf.yf
and lf.yf = wlcc.yf
and wlcc.yf = zzcc.yf
and wlcc.qxm like '1001%'
and dyhlf.dpyf = '201412'
group by lb.id, lb.mc, lb.zxdj, dyhlf.dyhid)) .
这个是别人写的. 乍看一下跟以往看到的有些风格不一样.分析一下是这样的.通常的代码是判断查询月份和当前月份是不是一样. iscurrent . 如果是当前月份就查询当前月的表. 否则查询历史表.
这里unionall了下.前一半查的是历史表,后一半查的是当前表.参数是201412 . 如果是当前月前一半查到0. 如果是历史月.后一半查到0 .最外层是sum 反正就是查一个. 不会两个都不是0 . 结果一样 这里耍了个小聪明. 不知效率如何