2011-09-26 46 views
1

我正在精炼一个脚本,以便它可以自动地由最终用户维护&。需要帮助设计用于SQL选择的规则表

之前,我在this SO帖子中提到过这个脚本的一部分。

由于Randyhis中描述的答案中,SQL语句的逻辑应该用表和连接的组合来代替,以实现相同的最终结果。


的基本情况和目标如下:

目前,该脚本会自动分配的顾问根据一套复杂的,涉及多个变量规则的学生。

由于员工(顾问雇用/解雇),专业(增加/删除的项目)和信用时间限制(确定顾问所需的最短时间)的变化,终端方案的规则将随时间而改变。

这些规则需要在脚本/ SQL之外维护,以便最终用户(院长/部门负责人)可以管理终端场景。

需要创建自定义表来有效地管理这些规则。


下面是目前被用来执行这些规则的SQL:

SELECT DISTINCT  s.id stu_id, 
        stu_id.fullname stu_name, 
        p.major1 major, 
        p.minor1 minor, 
        s.reg_hrs, 
        NVL(st.cum_earn_hrs,0) ttl_hrs, 
        p.adv_id curr_adv_id, 
        adv_id.fullname curr_adv_name, 
        CASE WHEN (p.adv_id <> 35808 AND p.major1 = 'NS')     THEN (1165) 
          WHEN (p.adv_id = 35808 AND p.major1 = 'NS')     THEN (35808) 
          WHEN (p.adv_id = 9179 AND p.major1 = 'DART')     THEN (9179) 
          WHEN (p.minor1 IN ('RT','RESP') AND st.cum_earn_hrs >= 24) THEN (70897) 
          WHEN (p.major1 IN ('CDSC','CDSD'))       THEN (52125) 
          WHEN (p.major1 IN ('CA','CB'))        THEN (24702) 
          WHEN (p.minor1 = 'NURS')          THEN (51569) 
          WHEN (p.major1 = 'LEG')          THEN (13324) 
          WHEN (p.major1 = 'CC')          THEN (73837) 
          WHEN (p.major1 = 'CCRE')          THEN (1133) 
          WHEN ((p.adv_id IN (SELECT DISTINCT id FROM fac_rec WHERE stat = 'I')) 
            OR (st.cum_earn_hrs < 24 AND (p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0 AND min_hrs >= 24)) 
            OR (s.id NOT IN (SELECT DISTINCT stu.id FROM stu_acad_rec stu, sess_info si WHERE stu.yr = si.prev_yr AND stu.sess = si.prev_sess AND stu.reg_hrs > 0 AND stu.reg_stat IN ('C','R') AND stu.prog = 'UNDG')) 
            OR ((p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat <> 'A' OR max_stu <= 0)) 
            OR ((p.adv_id||p.major1) NOT IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0))) 
          THEN (9238) 
          ELSE (p.adv_id) 
        END  new_adv_id, 
        CASE WHEN (p.adv_id <> 35808 AND p.major1 = 'NS')     THEN ('Deborah') 
          WHEN (p.adv_id = 35808 AND p.major1 = 'NS')     THEN ('Veronica') 
          WHEN (p.adv_id = 9179 AND p.major1 = 'DART')     THEN ('Stella') 
          WHEN (p.minor1 IN ('RT','RESP') AND st.cum_earn_hrs >= 24) THEN ('Lisa') 
          WHEN (p.major1 IN ('CDSC','CDSD'))       THEN ('Joanne') 
          WHEN (p.major1 IN ('CA','CB'))        THEN ('Barbara') 
          WHEN (p.minor1 = 'NURS')          THEN ('Karen') 
          WHEN (p.major1 = 'LEG')          THEN ('Nancy') 
          WHEN (p.major1 = 'CC')          THEN ('Alberta') 
          WHEN (p.major1 = 'CCRE')          THEN ('Naomi') 
          WHEN ((p.adv_id IN (SELECT DISTINCT id FROM fac_rec WHERE stat = 'I')) 
            OR (st.cum_earn_hrs < 24 AND (p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0 AND min_hrs >= 24)) 
            OR (s.id NOT IN (SELECT DISTINCT stu.id FROM stu_acad_rec stu, sess_info si WHERE stu.yr = si.prev_yr AND stu.sess = si.prev_sess AND stu.reg_hrs > 0 AND stu.reg_stat IN ('C','R') AND stu.prog = 'UNDG')) 
            OR ((p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat <> 'A' OR max_stu <= 0)) 
            OR ((p.adv_id||p.major1) NOT IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0))) 
          THEN ('Staff') 
          ELSE (adv_id.fullname) 
        END  new_adv_name, 
        CASE WHEN (p.adv_id <> 35808 AND p.major1 = 'NS')     THEN ('NS majors not assigned to Veronica go to Debbie') 
          WHEN (p.adv_id = 35808 AND p.major1 = 'NS')     THEN ('NS majors stay with Veronica') 
          WHEN (p.adv_id = 9179 AND p.major1 = 'DART')     THEN ('DART majors stay with Stella') 
          WHEN (p.minor1 IN ('RT','RESP') AND st.cum_earn_hrs >= 24) THEN ('RT-RESP minors go to Lisa') 
          WHEN (p.major1 IN ('CDSC','CDSD'))       THEN ('CDSC-CDSD majors go to Joanne') 
          WHEN (p.major1 IN ('CA','CB'))        THEN ('CA-CB majors go to Barbara') 
          WHEN (p.minor1 = 'NURS')          THEN ('NURS minors go to Karen') 
          WHEN (p.major1 = 'LEG')          THEN ('LEG majors go to Nancy') 
          WHEN (p.major1 = 'CC')          THEN ('CC majors go to Alberta') 
          WHEN (p.major1 = 'CCRE')          THEN ('CCRE majors go to Naomi') 
          WHEN (p.adv_id IN (SELECT DISTINCT id FROM fac_rec WHERE stat = 'I')) 
          THEN ('Current advisor is inactive') 
          WHEN (st.cum_earn_hrs < 24 AND (p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0 AND min_hrs >= 24)) 
          THEN ('Total credits for this student did not meet the advisor reqs for this major') 
          WHEN (s.id NOT IN (SELECT DISTINCT stu.id FROM stu_acad_rec stu, sess_info si WHERE stu.yr = si.prev_yr AND stu.sess = si.prev_sess AND stu.reg_hrs > 0 AND stu.reg_stat IN ('C','R') AND stu.prog = 'UNDG')) 
          THEN ('This student did not attend '||si.prev_sess||si.prev_yr) 
          WHEN ((p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE (stat <> 'A' OR max_stu <= 0))) 
          THEN ('Current advisor is not advising students with this major') 
          WHEN ((p.adv_id||p.major1) NOT IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0)) 
          THEN ('Current advisor is not advising students with this major') 
          ELSE ('Student will stay with current advisor') 
        END  change_comm 
FROM    stu_acad_rec s, 
        prog_enr_rec p, 
        OUTER stu_stat_rec st, 
        id_rec stu_id, 
        id_rec adv_id, 
        sess_info si 
WHERE    s.id = p.id 
        AND s.id = st.id 
        AND s.id = stu_id.id 
        AND p.adv_id = adv_id.id 
        AND s.yr = si.curr_yr 
        AND s.sess = si.curr_sess 
        AND s.reg_hrs > 0 
        AND s.reg_stat IN ('C','R') 
        AND s.prog = 'UNDG' 
        AND p.prog = 'UNDG' 
        AND st.prog = 'UNDG' 
        AND s.id NOT IN (3,287,9238,59999) {System test use IDs} 
INTO TEMP   stu_list 
WITH NO LOG; 

我想建一个表来容纳所有这些规则,但从来没有建立一个表这种类型的目的。

我的想法到目前为止是这种结构的表格:

adv_assign_rules 
---------------- 
rule_no 
curr_adv_id 
major1 
major2 
minor1 
minor2 
cum_earn_hrs 
new_adv_id 
rule_desc 
rule_no_ref 
rule_stat 
rule_date 

此表的例子行,将容纳在SQL选择第一种情况可能是这样的:

rule_no   1 
curr_adv_id  !35808 
major1   =NS 
major2 
minor1 
minor2 
cum_earn_hrs 
new_adv_id  1165 
rule_desc  NS majors not assigned to 35808 go to Debbie 
rule_no_ref 
rule_stat  A 
rule_date  2011-09-26 15:02:26.000 

是这样的桌子有什么缺点?这种设置可以适应所有这些规则吗?有谁知道在哪里可以找到用于类似目的的表格的例子吗?

我在寻找有关改进的建议和/或针对此问题的替代解决方案。这些案例陈述中的“其他”情景表明,学生顾问不需要改变。此外,其中逻辑数量最多的情况(在“else”情况下的最后一种情况)将新顾问程序默认为9238 - 这表示已有的其他逻辑将用于分配新的adivsor。以前的所有案例都是默认场景,这些场景是不符合分配新顾问规则的特殊情况 - 这些是我尝试以表格格式重新创建的特例。

更新:我还在寻找重现和/或场景的功能。我添加了两个字段:rule_no & rule_no_ref这是一个序列号(自动递增)和对另一个规则序列号的引用。

在此先感谢任何可以提供的帮助!

+0

我想你可能想为此保留'CASE'。没有某种类型的循环就很难复制短路行为。一种可能性是使用动态SQL,并为每个场景填充“CASE”标准。 – JNK

+0

如果我是唯一一个维护它的人,我会保留它,但最终用户需要一种方法来调整这些规则。我会看看你的其他建议 - 谢谢 – CheeseConQueso

回答

-1

我会去解决此稍有不同:

1)创建一个表rule_type

id 
name 

2)创建表RULE_SET

id -- rule 
type -- relation to talbe 1 
name 
staff_group -- relation to the appropriate staff group for that rule 
student_group -- relation to the appropriate student group for that rule 
val_int --- for the rules that require numeric number 
val_chr --- for rules that require integer values 
val_date --- for date values rules 
date_start --- start date of a rule 
date_end --- end date of a rule 

你也可以做出间隔paranters领域像整数范围从X ... Y像: val_int_start val_int_end 或任何其他对于这个问题

然后创建一个存储过程将处理规则和评估适当的数据

R数据类型

这种方法的很好的思考是,你会真的很少需要从长远来看,编写新的东西

+0

感谢您的答案...事情是,这不占比较属性(例如:<>> = <= ==),也没有定义哪些字段比较 – CheeseConQueso