有一员工表如下:
员工编号  姓名   正式员工    考核分数  考核奖金
001  A   是  1000 
002  B   是  2000   
003  C   是  800   
004  D   否  600 
005  E   是  1500    
006  F   否  3000  1、以上表格中考核奖金为空,需要通过循环计算然后把结果写到考核奖金中
2、如果是正式员工,考核奖金=考核分数*0.1元
3、如果不是正式员工,同时考核分数1000分以下的,没有奖金
                       考核分数1000分-2000分的,考核奖金=考核分数*0.2元
                       考核分数2000分-3000分的,考核奖金=考核分数*0.3元4、我目前是将以上表中的数据读到DataGridView表格控件中,然后一行行循环来处理,最后写到相应的表格中。
5、这种计算如果放在SQL端应该怎么处理?我的思路是不是有错误? 我的格很灵活,可以按需求来建表,请问大家有没有更灵活,效率更高的方法? 谢谢。
                     

解决方案 »

  1.   

    SELECT 
        员工编号,
        姓名,
        正式员工,
        考核分数,
        考核奖金=CASE WHEN 正式员工='是'
                        THEN 考核分数*1.1
                     ELSE
                         CASE WHEN 考核分数 BETWEEN 1000 AND 2000
                                  THEN 考核分数*1.2
                              WHEN 考核分数 BETWEEN 2000 AND 3000
                                  THEN 考核分数*1.3
                              ELSE 0 
                          END
                 END
    FROM tb
      

  2.   

    UPDATE tb SET 考核奖金=
    CASE WHEN 正式员工='是' THEN 考核分数 * 0.1
    ELSE  --非正式员工了
    WHEN 考核分数 >2000 THEN 考核分数 * 0.3
    WHEN 考核分数 >1000 AND 考核分数 <2000 THEN 考核分数*0.2
    ELSE
    0
    END
    END
      

  3.   

    UPDATE tb SET
        考核奖金=CASE WHEN 正式员工='是'
                        THEN 考核分数*1.1
                     ELSE
                         CASE WHEN 考核分数 BETWEEN 1000 AND 2000
                                  THEN 考核分数*1.2
                              WHEN 考核分数 BETWEEN 2000 AND 3000
                                  THEN 考核分数*1.3
                              ELSE 0 
                          END
                 END
      

  4.   

    DECLARE @TB TABLE(员工编号 VARCHAR(3), 姓名 VARCHAR(2),  正式员工 NVARCHAR(1),    考核分数 INT,  考核奖金 INT)
    INSERT @TB
    SELECT '001',  'A',  N'是',  1000,0 UNION ALL 
    SELECT '002',  'B',  N'是',  2000,0 UNION ALL 
    SELECT '003',  'C',  N'是',  800,0 UNION ALL 
    SELECT '004',  'D',  N'否',  600,0 UNION ALL 
    SELECT '005',  'E',  N'是',  1500,0 UNION ALL 
    SELECT '006',  'F',  N'否',  3000,0SELECT CASE WHEN 正式员工=N'是' THEN 考核分数*0.1
            ELSE CASE WHEN 考核分数<1000 THEN 0
               WHEN 1000<=考核分数 AND 考核分数<=2000 THEN 考核分数*0.2
               WHEN 2000<考核分数 AND 考核分数<=3000 THEN 考核分数*0.3
                                         END
                     END AS 考核奖金 
    FROM @TB
    /*
    考核奖金           
    -------------- 
    100.0
    200.0
    80.0
    .0
    150.0
    900.0
    */
      

  5.   

    谢谢各位,用case when 可以解决还有另一个问题: 考核分数1000分-2000分的,考核奖金=考核分数*0.2元 
     考核分数2000分-3000分的,考核奖金=考核分数*0.3元 
    1、考核分数1000分 2000分,0.2元,0.3元等这些数据是不固定的,我目前目前我是用一些字段来保存这些数据,当公司需要变更时,用户只需要自己把这些设置调出来自行修改,不需要改程序。
    2、如果用case when来解决,要去另一个表中调用这些数据可能就会搞复杂了。请问有没有其它的办法来实现?
    3、还是直接在界面上把存储过程调出来,让用户直接改存储过程? 这样有点不安全,怕他们改错。
      

  6.   

    不复杂..也是一样搞.
    反而更简单..两个表join时指定范围即可.
      

  7.   

    TO 小梁 (人一生必做三件事.自欺!欺人!被人欺!):
    你的意思是用join把两个表连接起来,然后把具体的数据比如1000分,2000分改成另一个表的字短就行了?
      

  8.   

    ---------------------------------
    --  Author: liangCK 小梁
    --  Date  : 2008-11-19 18:05:43
    ---------------------------------
     
    --> 生成测试数据: @tb1
    DECLARE @tb1 TABLE (员工编号 VARCHAR(3),姓名 VARCHAR(1),正式员工 VARCHAR(2),考核分数 INT,考核奖金 NUMERIC(10,2))
    INSERT INTO @tb1
    SELECT '001','A','是',1000,null UNION ALL
    SELECT '002','B','是',2000,null UNION ALL
    SELECT '003','C','是',800,null UNION ALL
    SELECT '004','D','否',600,null UNION ALL
    SELECT '005','E','是',1500,null UNION ALL
    SELECT '006','F','否',3000,null
     
    --> 生成测试数据: @tb2
    DECLARE @tb2 TABLE (初始值 INT,终止值 INT,奖金 NUMERIC(2,1))
    INSERT INTO @tb2
    SELECT 1000,2000,0.2 UNION ALL
    SELECT 2001,3000,0.3--SQL查询如下:UPDATE a SET
        考核奖金=CASE WHEN 正式员工='是'
                         THEN a.考核分数 * 0.1
                      ELSE
                          a.考核分数*b.奖金
                  END
    FROM @tb1 AS a
        JOIN @tb2 AS b
            ON a.考核分数 BETWEEN b.初始值
                        AND b.终止值
     
    SELECT * FROM @tb1/*
    员工编号 姓名   正式员工 考核分数        考核奖金
    ---- ---- ---- ----------- ---------------------------------------
    001  A    是    1000        100.00
    002  B    是    2000        200.00
    003  C    是    800         NULL
    004  D    否    600         NULL
    005  E    是    1500        150.00
    006  F    否    3000        900.00(6 行受影响)
    */
      

  9.   

    一样的UPDATE a SET 考核奖金 = 考核分数 * n
         FROM tb a
    INNER JOIN
     (
         SELECT 0 d1,1000 d2, n=0.0,t='否'
         UNION ALL
         SELECT 1000,2000,0.2,'否'
         UNION ALL
         SELECT 2000,3000,0.3,'否'
         UNION ALL
         SELECT 0,100000000,0.1 '是'
    ) b
         ON 是否转正=t AND 考核分数>=d1 AND 考核分数<d2
      

  10.   

    非常感谢各位的回复,你们的方法让我的程序简单了很多,用SQL就可以简单实现,省了我在界面上写很多代码,原来是把数据从SQL中读到界面,然后一行行分析处理,最后再写回SQL数据库,现在很省事了,真是羡慕你们的SQL语句能随心所欲的应用。不过你们的代码我还要花些时间去学习,不能光是拿来就用。明天结贴。
      

  11.   

    程序简单,不一定运行简单.前台能处理的复杂一点的事情,最好不要拿到数据库里来处理.因为程序设计主要考虑算法,而数据库主要考虑的是存储.用一些简单的运算测试一下就会知道,MSSQL的运算比一般前台程序慢多了.
      

  12.   

    感谢晴天的意见。目前来说用户的配置不是很好,所以放在客户端来处理也会慢。用户大部分电脑的配置是赛扬的CPU,内存256M,并且同时安装了瑞星杀毒软件,360安全卫士,360的ARP防火墙,瑞星卡卡,360密码保险箱。操作系统是XP。通过检查,我发现他们的系统只运行XP,就要占用250M左右的内存,加上这些安全软件,不做任何工作的情况下内存是480M左右(用了虚拟内存),再开Outlook和Word和Excel就是半天没有反应。不过我只是负责开发软件,对于客户的PC配置以及这些情况只能是建议他们怎么做。所以我考虑用SQL端来处理,毕竟服务器的配置有1G的内存。同时安装这么多的安全软件你们觉得很好笑吧,可是这就是事实。
      

  13.   

     
    前台和客户端不是一回事.
    如果是C/S结构,可以是服务器端与数据库服务器连接,客户端与服务器端连接.如果是B/S结构,那就是WEB服务器与数据库连接.