优化前SQL:

 select rownum r,
        a.*,
        (select count(0) ymbjgrs
           from (select c.xh, b.bjdm, count(*) bjgks
                   from cjb c
                   left join view_xsjbxx b
                     on c.xh = b.xh
                  where c.xn = '2016-2017'
                    and c.xq = '01'
                    and c.cj <
                        (select dycj from cjdzb where dydj like '%不及格%')
                  group by c.xh, b.bjdm)
          where bjgks =1 or bjgks = 1
            and bjdm = a.bjdm) ymbjgrs,
             (select count(0) lmbjgrs
           from (select c.xh, b.bjdm, count(*) bjgks
                   from cjb c
                   left join view_xsjbxx b
                     on c.xh = b.xh
                  where c.xn = '2016-2017'
                    and c.xq = '01'
                    and c.cj <
                        (select dycj from cjdzb where dydj like '%不及格%')
                  group by c.xh, b.bjdm)
          where bjgks =1 or bjgks = 2
            and bjdm = a.bjdm) lmbjgrs,
             (select count(0) smbjgrs
           from (select c.xh, b.bjdm, count(*) bjgks
                   from cjb c
                   left join view_xsjbxx b
                     on c.xh = b.xh
                  where c.xn = '2016-2017'
                    and c.xq = '01'
                    and c.cj <
                        (select dycj from cjdzb where dydj like '%不及格%')
                  group by c.xh, b.bjdm)
          where bjgks =1 or bjgks = 3
            and bjdm = a.bjdm) smbjgrs,
             (select count(0) simbjgrs
           from (select c.xh, b.bjdm, count(*) bjgks
                   from cjb c
                   left join view_xsjbxx b
                     on c.xh = b.xh
                  where c.xn = '2016-2017'
                    and c.xq = '01'
                    and c.cj <
                        (select dycj from cjdzb where dydj like '%不及格%')
                  group by c.xh, b.bjdm)
          where bjgks =1 or bjgks = 4
            and bjdm = a.bjdm) simbjgrs,
             (select count(0) wmbjgrs
           from (select c.xh, b.bjdm, count(*) bjgks
                   from cjb c
                   left join view_xsjbxx b
                     on c.xh = b.xh
                  where c.xn = '2016-2017'
                    and c.xq = '01'
                    and c.cj <
                        (select dycj from cjdzb where dydj like '%不及格%')
                  group by c.xh, b.bjdm)
          where bjgks =1 or bjgks = 5
            and bjdm = a.bjdm) wmbjgrs,
        (select count(0) bjrs from view_xsjbxx d where d.bjdm = a.bjdm) bjrs,
        (select avg(jd) from (
       select AVG(d.jd)  jd,c.bjdm bjdm,d.kcmc from view_xszz_xsjd_11799 d left join cjb b on d.xh = b.xh left join view_xsjbxx c on d.xh = c.xh where d.xn = '2016-2017' and b.xq = '01' group by c.bjdm,d.kcmc
       ) where bjdm = a.bjdm) jd,
         (select avg(xf) from (
       select c.bjdm bjdm,d.kcmc,avg(d.xf) xf from view_xszz_xsjd_11799 d left join cjb b on d.xh = b.xh left join view_xsjbxx c on d.xh = c.xh where d.xn = '2016-2017' and b.xq = '01' group by c.bjdm,d.kcmc
       ) where bjdm = a.bjdm) xf,
        (select count(0) ksm
           from (select kcmc
                   from CJB t
                  where xn = '2016-2017'
                    and xq = '01'
                  group by kcmc)) kskms
                   
   from (select a.nj || '!!luojw!!' || a.xydm || '!!luojw!!' || a.zydm ||
                '!!luojw!!' || a.bjdm pk,
                a.nj,
                a.xymc,
                a.xydm,
                a.zydm,
                a.zymc,
                a.bjdm,
                f.qqqh,
                a.bjmc,
                nvl(d.rs, 0) rs,
                fdyxm,
                bzrxm,
                (case
                  when length(fdyxm) > 10 then
                   substr(fdyxm, 1, 10) || '...'
                  else
                   fdyxm
                end) fdy,
                (case
                  when length(bzrxm) > 10 then
                   substr(bzrxm, 1, 10) || '...'
                  else
                   bzrxm
                end) bzr,
                fdyzgh,
                bzrzgh,
                case
                  when fdyxm is null then
                   '否'
                  else
                   '是'
                end sfyszfdy,
                case
                  when bzrxm is null then
                   '否'
                  else
                   '是'
                end sfyszbzr
           from view_njxyzybj_all a
           left join (select a.bjdm,
                            WM_CONCAT(a.zgh) fdyzgh,
                            WM_CONCAT(b.xm || ' ' || b.lxdh) fdyxm
                       from fdybjb a
                       left join fdyxxb b
                         on a.zgh = b.zgh
                      group by a.bjdm) b
             on a.bjdm = b.bjdm
           left join (select a.bjdm,
                            WM_CONCAT(a.zgh) bzrzgh,
                            WM_CONCAT(b.xm || ' ' || b.lxdh) bzrxm
                       from bzrbbb a
                       left join fdyxxb b
                         on a.zgh = b.zgh
                      group by a.bjdm) c
             on a.bjdm = c.bjdm
           left join (select bjdm, count(xh) rs
                       from xsxxb
                      where sfzx = '在校'
                         or sfzx is null
                      group by bjdm) d
             on a.bjdm = d.bjdm
           left join (select bjdm, count(xh) fzxrs
                       from xsxxb
                      where sfzx = '不在校'
                      group by bjdm) e
             on a.bjdm = e.bjdm
           left join (select bjdm, qqqh from XG_bjxxb_12303) f
             on a.bjdm = f.bjdm
          where (nvl(e.fzxrs, 0) = 0 and nvl(d.rs, 0) = 0)
             or nvl(d.rs, 0) > 0
          order by nj desc, xydm, zydm, bjdm) a
  where 1 = 1
    and (1 = 1);
优化后SQL:


select b.fdyxm,
       a.nj,
       a.zymc,
       a.bjmc,
       c.bjrs,
       c.xy,
       d.kskm,
       round(f.xfs / c.bjrs,2) as pjxfjd,
       i.ymbjgrs,
       j.lmbjgrs,
       k.smbjgrs,
       l.simbjgrs,
       m.wmbjgrs,
       (i.ymbjgrs + j.lmbjgrs + k.smbjgrs + l.simbjgrs + m.wmbjgrs) as bjgzrs,
       concat(round(nvl((i.ymbjgrs + j.lmbjgrs + k.smbjgrs + l.simbjgrs +
                    m.wmbjgrs) / c.bjrs,0) * 100,
                    2),
              '%') as bjgbl
  from view_njxyzybj a
  left join (select a.bjdm,
                    WM_CONCAT(a.zgh) fdyzgh,
                    WM_CONCAT(b.xm) fdyxm
               from fdybjb a
               left join fdyxxb b
                 on a.zgh = b.zgh
              group by a.bjdm) b
    on b.bjdm = a.bjdm
  left join (select count(xh) bjrs, bjdm,xy from xsxxb group by bjdm,xy) c
    on c.bjdm = a.bjdm
  left join (select count(0) kskm, bb.bjdm
               from cjb aa
               left join xsxxb bb
                 on aa.xh = bb.xh
              group by bb.bjdm, aa.kcmc) d
    on d.bjdm = a.bjdm
  left join (select sum(a.xf * a.jd) / sum(a.xf) xfs, b.bjdm
               from view_xszz_xsjd_11799 a
               left join xsxxb b
                 on a.xh = b.xh
               left join cjb c
                 on a.xh = c.xh
               where c.xn = '2016-2017'
                 and c.xq = '01'
              group by b.bjdm) f
    on f.bjdm = a.bjdm

  left join (select count(0) ymbjgrs, bjdm, bjgks
               from (select c.xh, b.bjdm, count(*) bjgks
                       from cjb c
                       left join xsxxb b
                         on c.xh = b.xh
                      where c.xn = '2016-2017'
                        and c.xq = '01'
                        and c.cj <
                            (select dycj from cjdzb where dydj like '%不及格%')
                      group by c.xh, b.bjdm)
              group by bjdm, bjgks) i
    on i.bjdm = a.bjdm
   and i.bjgks = 1
  left join (select count(0) lmbjgrs, bjdm, bjgks
               from (select c.xh, b.bjdm, count(*) bjgks
                       from cjb c
                       left join xsxxb b
                         on c.xh = b.xh
                      where c.xn = '2016-2017'
                        and c.xq = '01'
                        and c.cj <
                            (select dycj from cjdzb where dydj like '%不及格%')
                      group by c.xh, b.bjdm)
              group by bjdm, bjgks) j
    on i.bjdm = a.bjdm
   and i.bjgks = 2
  left join (select count(0) smbjgrs, bjdm, bjgks
               from (select c.xh, b.bjdm, count(*) bjgks
                       from cjb c
                       left join xsxxb b
                         on c.xh = b.xh
                      where c.xn = '2016-2017'
                        and c.xq = '01'
                        and c.cj <
                            (select dycj from cjdzb where dydj like '%不及格%')
                      group by c.xh, b.bjdm)
              group by bjdm, bjgks) k
    on i.bjdm = a.bjdm
   and i.bjgks = 3
  left join (select count(0) simbjgrs, bjdm, bjgks
               from (select c.xh, b.bjdm, count(*) bjgks
                       from cjb c
                       left join xsxxb b
                         on c.xh = b.xh
                      where c.xn = '2016-2017'
                        and c.xq = '01'
                        and c.cj <
                            (select dycj from cjdzb where dydj like '%不及格%')
                      group by c.xh, b.bjdm)
              group by bjdm, bjgks) l
    on i.bjdm = a.bjdm
   and i.bjgks = 4
  left join (select count(0) wmbjgrs, bjdm, bjgks
               from (select c.xh, b.bjdm, count(*) bjgks
                       from cjb c
                       left join xsxxb b
                         on c.xh = b.xh
                      where c.xn = '2016-2017'
                        and c.xq = '01'
                        and c.cj <
                            (select dycj from cjdzb where dydj like '%不及格%')
                      group by c.xh, b.bjdm)
              group by bjdm, bjgks) m
    on i.bjdm = a.bjdm
   and i.bjgks > 4
 

思路方面:首先要理清,哪张表作为主表,各个关联表和主表关系。将各个表与主表匹配的字段分析,哪些是需要用到的,哪些是可以舍弃的。

优化过程中遇到的问题和新get技能小结:

1.SQL语句报错,不是单组分组函数   --->首先,用聚合函数count(),sum()时,必须group by,其次要注意,单独的group by使用时,select后面不能是 * ,而应该是具体的要group by的列。

2.查询结果去重,比如现在查询一个学校的各个系及格人数,查询结果出来,一般有4条软件工程,4条机械工程,4条。。。原因是,每个学院又包含大一~大四的学生,故此处应该group by一下学院代码。

3.rownum和order by的执行顺序问题:

取网上一个例子:select id1,id2 from t_tablename where rownum<3 order by c_date desc

这个语句会先从结果集中取前三条记录,再对这3天记录按日期排序。如果设计者向先对日期排序,再取前三天记录,那么就不会得到正确的结果。

那么如果想得到先order by再rownum,则按如下操作:

select id1,id2 from (select id1,id2 from t_tablename order by c_date desc) where rownum<3

参考博客:https://blog.csdn.net/wulex/article/details/79996892

4.order by 和 group by的区别:

order by 从英文里理解就是行的排序方式,默认的为升序。 order by 后面必须列出排序的字段名,可以是多个字段名。

group by 从英文里理解就是分组。必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标志字段。

在使用聚合函数时,使用group by 的目的就是要将数据分类汇总。

在sql命令格式使用的先后顺序上,group by 先于 order by。

参考博客:http://www.cnblogs.com/xiayang/articles/1395876.html

5.SQL中的nvl(column,0),nvl(column1,column2,column3),ifNull()区别

nvl()是oracle数据库中判断字段值是否为空的函数,

ifNull()是MySQL数据库中判断字段值是否为空的函数。

nvl(column1,column2)该函数目的是把一个空函数转为一个实际值。其中column1,column2的值可以是数字型、字符型、日期型,但是表达式1和表达式2的值必须是同一类型。

nvl(column,0):若column字段值为空,则返回0.

nvl(column1,column2,column3):若column1字段为空则返回column3,若不为空返回column2.

参考文档:https://blog.csdn.net/qq_24549805/article/details/51892651

6.round(m,n)函数

用于把m数值字段四舍五入n位,n为小数点后保留位数。

7.concat(m,n)函数

用于将字符串m和n连接起来,拼成一个新的字符串m+n。

例如除法运算后的小数,可以用concat(round(m/n,2) * 100,'%'),之所以要乘以100,是为了匹配后面的%,先将小数乘以100,再添加%,但*100运算,必须在round()函数的外面,如此才能不影响结果的精确性。

Oracle中 || 也可以用来拼接,例如:

select a.sybz1 || a.sybz2 || a.sybz3 as syd, a.bjdm, b.mzmc
               from xsxxb a
               left join mzdmb b
                 on a.mz = b.mzdm

其中sybz1存储省份,sybz2存储市级,sybz3存储县级,故返回值为省市县。

8.查询结果以百分比形式返回时,小数点前面的0消失,如图:

优化SQL笔记整理

原因: oracle  数据库 字段值为小于1的小数时,使用char类型处理,会丢失小数点前面的0

解决方案: <1>使用decode函数:

   既然小于1的小数首位必然是'.',那就判断首位是否为'.',是则在前面加上'0'即可 

  select decode(substr(num,1,1),'.','0'||num,num) from t1_number

<2>比较笨拙的方式:返回结果以小数返回,在页面和需要显示百分比的地方,做添加%处理。

9.TNS无监听程序:

出现原因:登录新数据库连接的时候出现,是数据库的链接地址有错。

优化SQL笔记整理

解决方案:检查IP,端口和链接参数,与配置文件对比。

这应该属于比较低级错误,但我今日首次遇到,故记载之。

相关文章: