首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 简化语句 [已结贴,结贴人:jjwwang]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:09:43 楼主
    ...
    sum(case when rq <'1997-10-1' and left(BM,1)='0' then 1 else 0 end) _0_sum,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000502' then 1 else 0 end) _0_1,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000201' then 1 else 0 end) _0_2,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000404' then 1 else 0 end) _0_3,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000403' then 1 else 0 end) _0_4,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and left(BM,4)='0008' then 1 else 0 end) _0_5,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='0010' and BM <>'001001'then 1 else 0 end),
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='001001' then 1 else 0 end) _0_7,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000503' then 1 else 0 end) _0_8,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000504' then 1 else 0 end) _0_9,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000507' then 1 else 0 end) _0_10,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000601' then 1 else 0 end) _0_11,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and left(BM,4)='0012' then 1 else 0 end) _0_12,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM in('000510','000509') then 1 else 0 end) _0_13,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000505' then 1 else 0 end) _0_14,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM='000506' then 1 else 0 end) _0_15,
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM not in('000502','000201','000404','000403','001001','000503',
    '000504','000507','000601','000510','000509','000505','000506')
        and left(BM,4) not in('0008','0010','0012') then 1 else 0 end) _0_16,

    一个储存过程一段代码。
    即在列转行的时候, 上面case 很多条件, 最后求不包含上面case条件的做统计,很累。
    有什么好办法优化一下,即不用再写


    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:15:161楼 得分:9
    rq <'1997-10-1' and left(BM,1)='0'
    这个可以放到where后面
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ojuju10
    • 等级:
    发表于:2008-04-08 11:18:412楼 得分:7

    写成动态的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:19:463楼 得分:7
    所有的sum,case when条件中都有 rq <.... and left..这一句.
    那么,将这一句提出来,放到 where 过滤中去.
    那么将是

    sum(1) _0_sum
    sum(case when bm='000502' then 1 else 0 end' _0_1,
    sum(case when bm='000201' then 1 else 0 end' _0_2,
    ...

    这样的语句.

    如果改动引起了记录行的变化(毕竟增加了where 过滤),那么看你实际的需要,是否要把不符条件的也列出来,只不过sum值为0. 如果要列出来,那么多一次连表就可以了.但效率会降一点.偷懒的后果.

    不含case when不可能,由于你条件不致,也就是没有规则,无法用动态行转列.即便是可以用动态行转列来写,其实还是case when完成的.

    要怕麻烦,就放到前台程序去做.

    只想告诉你一点,在数据库端做行转列都是没意义的事, 有人说,是老板要求这么做的,我只想问,老板会趴在你的查询分析器上看结果?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:20:584楼 得分:7
    sum(case when rq <'1997-10-1' and left(BM,1)='0' and BM not in('000502','000201','000404','000403','001001','000503',
    '000504','000507','000601','000510','000509','000505','000506') 
        and left(BM,4) not in('0008','0010','0012') then 1 else 0 end) _0_16,

    这个可以去掉,或者改一下:
    SQL code
    select *, _0_16=_0_sum - _0_1 - _0_2 - _0_3 - ... - _0_15 from ( select ... count(1) _0_sum, sum(case when BM='000502' then 1 else 0 end) _0_1, sum(case when BM='000201' then 1 else 0 end) _0_2, ... where rq<'1997-10-1' and left(BM,1)='0' ... ) T
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:22:125楼 得分:0
    说明:

    从一个表进行统计, 性别,学历, 职业,职称,国籍 ....等等很多项.
    并且统计时的条件也不一样的。
    对性别 统计进要限定年龄等。 职业统计时要限定性别等....其它...
    所以
    select sum(case when .....) as 字段名,
    ....

    from People
    (where 是不确定的,所以不能限制。直接在case when 这来限制.)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:23:396楼 得分:7
    left(BM,1)='0' and BM='000502'
    这个两个重复了,后面一个成立话,前面一个肯定也成立,所以前面一个直接去掉
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:29:427楼 得分:0
    我这个报表要统计200来项的值。有的bm有2000多种。
    再简单说, 我就是不要再写下面这些代码了。
    and left(bm,2) <>'59' and
    left(bm,4)not in('5101','5103','5104','5105','5106','5107',
    '5109','5122','5111','5118','5120','5121',
    '5123','5124','5125','5126','5127','5132',
    '5133','5134','5136','5201','5207','5209',
    '5210','5212','5213','5215','5216','5301',
    '5306','5307','5401','5405','5407','5409',
    '5513','5510','5605','5606','5607','5608',
    '5609','5612','5701','5702','5703','5704',
    '5705','5709','5710','5711','5712','5801',
    '5802','5804','5805','5806') then 1 else 0 end) _5_57,
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:37:478楼 得分:0
    本来想 delcare @v1, @v2, @v3..... @v200
    然后用游标,再
    if 
    else if
    else if
    else
      这里就不用再写那些代码了。

    再最后
    @v1 = @v2 + @3 +@X
    @v22 = @v33+@v41+@v55
    。。
    怕容易加错了。比如把@v42不小心加进去了。
    所以写成上面那样了, 结果也是累。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 11:59:289楼 得分:7
    SQL code
    --所有的case中都包含rq <'1997-10-1' and left(BM,1)='0',可以把rq <'1997-10-1' and left(BM,1)='0'放在最后的where条件中。这样可以缩小范围,并且减少判断。 count(1) _0_sum, sum(case when BM='000502' then 1 else 0 end) _0_1, sum(case when BM='000201' then 1 else 0 end) _0_2, sum(case when BM='000404' then 1 else 0 end) _0_3, sum(case when BM='000403' then 1 else 0 end) _0_4, sum(case when left(BM,4)='0008' then 1 else 0 end) _0_5, sum(case when BM='0010' and BM <>'001001'then 1 else 0 end), sum(case when BM='001001' then 1 else 0 end) _0_7, sum(case when BM='000503' then 1 else 0 end) _0_8, sum(case when BM='000504' then 1 else 0 end) _0_9, sum(case when BM='000507' then 1 else 0 end) _0_10, sum(case when BM='000601' then 1 else 0 end) _0_11, sum(case when left(BM,4)='0012' then 1 else 0 end) _0_12, sum(case when BM in('000510','000509') then 1 else 0 end) _0_13, sum(case when BM='000505' then 1 else 0 end) _0_14, sum(case when BM='000506' then 1 else 0 end) _0_15, sum(BM not in('000502','000201','000404','000403','001001','000503', '000504','000507','000601','000510','000509','000505','000506') and left(BM,4) not in('0008','0010','0012') then 1 else 0 end) _0_16, where rq <'1997-10-1' and left(BM,1)='0'
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 12:00:4410楼 得分:7
    最后一个_0_16掉了个case,楼主自己加下`
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 12:44:4511楼 得分:7
    not in --> in
    SQL code
    sum(BM in('000502','000201','000404','000403','001001','000503', '000504','000507','000601','000510','000509','000505','000506') or left(BM,4) in('0008','0010','0012') then 0 else 1 end) _0_16,
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • utpcb
    • 等级:
    发表于:2008-04-08 14:58:2812楼 得分:7
    up 看着都累啊 同情你搂住
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 15:04:1813楼 得分:7
    只要是业务需要,写一次怕什么麻烦

    要不用视图,写各种条件的,然后查询时用
    select *,[_0_sum]-[_0_1]-[_0_2]-...-[_0_15] as [_0_16]
    from view1
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-08 16:47:2014楼 得分:7
    能不能给点数据我实测下,我有想法
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ranzj
    • 等级:
    发表于:2008-04-09 17:11:1615楼 得分:7
    做个表值函数算了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 17:20:0916楼 得分:7
    好长
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 21:38:2217楼 得分:7
    晕倒
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved