需要找老师基本总和(1,2,3,4)

时间:2018-04-01 12:35:05

标签: mysql oracle

TEACHER_TB

NUMBER  VARCHAR VARCHAR VARCHAR DATE    NUMBER  NUMBER
TEACHER_ID  FIRST NAME  LAST NAME   GENDER  DOB SALARY_ID   SUBJECT_ID
1   Bob Sandreas    M   12-May-60   1   2
2   Michella    Farah   F   24-Dec-80   3   4
3   Montessa    Santos  F   10-Feb-73   3   8
4   John    Reyes   M   28-Feb-88   2   6
5   Lara    Saliba  F   15-Aug-73   2   10
6   Rizvi   Ibrahim M   9-May-65    1   3
7   Raphael Legaspi M   5-Sep-91    2   5
8   Alaa    Badawy  M   27-Jan-85   2   4
9   Jahangir    Alam    M   28-Jul-57   1   9
10  Peter   Parker  M   5-Jun-92    1   6
primary key                 foreign key salary_tb(salary_id)    foreign key subject_tb(subject_id)

SALARY_TB

NUMBER  VARCHAR VARCHAR VARCHAR VARCHAR VARCHAR VARCHAR
SALARY_ID   BASIC   HOUSING TRANSPORTATION  TELEPHONE   PPF TDS
1   Y   Y   Y   Y   Y   Y
2   Y   Y   N   N   Y   Y
3   Y   Y   N   N   N   Y
primary key                     

SALARY_COMPONENTS_TB

NUMBER  VARCHAR VARCHAR VARCHAR         
COMPONENT_ID    SALARY_COMPONENT    COMPONENT_TYPE  AMOUNT          
1   BASIC   EARNING 40000           
2   HOUSING EARNING 20000           
3   TRANSPORTATION  EARNING 10000           
4   TELEPHONE   EARNING 5000            
5   PPF DEDUCTION   5%          
6   TDS DEDUCTION   10%         

第一个问题

有3个表(TEACHER_TB,SALARY_TB,SALARY_COMPONENTS_TB),其中前2个表已链接,但没有与SALARY_COMPONENTS_TB的连接(没有表与SALARY_COMPONENTS_TB连接),所以我需要找出教师工资SALARY_COMPONENT(总和)。 / p>

第二个问题

我们可以在两个表之间没有任何关系的情况下链接两列吗?

1 个答案:

答案 0 :(得分:0)

  

"我们可以在两个表之间没有任何关系的情况下链接两列吗?"

当然。我们可以加入任何东西。只是有些连接是有意义的而其他人没有。外键的目的是强制实现关系。外键的存在也可以作为有意义的连接的指示。

  

"没有与SALARY_COMPONENTS_TB"

的关联

您需要根据SALARY_COMPONENTS_TB中的列和SALARY_TB中的行将SALARY_TB加入SALARY_COMPONENTS_TB。这是一个支点。执行此操作有多种不同的方法是MySQL,但硬编码值是最简单的(如果不是最易维护的,但请参见下面的注释)。

计算扣减是混乱的,因为相关的amount值存储为非数字字符串。 '10%'可能对人类友好,但最好存储一个适合算术的值,即0.10

无论如何这里是一个查询:

select t.teacher_id
        , t.salary_id
        , (sal.basic+sal.housing+sal.transportation+sal.telephone) as salary_gross
        , (sal.ppf + sal.tds) as salary_deduct
        , (sal.basic+sal.housing+sal.transportation+sal.telephone) 
                 - ( (sal.basic+sal.housing+sal.transportation+sal.telephone) 
                                              * (sal.ppf + sal.tds) ) as salary_net
from teacher_tb as t
join (
    select s.SALARY_ID
              , case when (basic='Y') then scb.amount else 0 end as basic
              , case when (housing='Y') then sch.amount else 0 end as housing
              , case when (transportation='Y') then sct.amount else 0 end as transportation
              , case when (telephone='Y') then scp.amount  else 0 end as telephone
              , case when (ppf='Y') then round(substring(ppf.amount,1, length(ppf.amount)-1)/100,3) else 0 end as ppf
              , case when (tds='Y') then round(substring(tds.amount,1, length(tds.amount)-1)/100,3) else 0 end as tds
    from salary_tb as s
        cross join           salary_components_tb scb
        cross join      salary_components_tb sch
        cross join      salary_components_tb sct
        cross join      salary_components_tb scp
        cross join      salary_components_tb ppf
        cross join      salary_components_tb tds
    where scb.salary_component = 'BASIC'
    and sch.salary_component = 'HOUSING'
    and sct.salary_component = 'TRANSPORTATION'
    and scp.salary_component = 'TELEPHONE'
    and ppf.salary_component = 'PPF'
    and tds.salary_component = 'TDS'
    ) as sal 
    on t.salary_id = sal.salary_id
;

a demo on SQL Fiddle here

人们常常不喜欢被告知他们正在使用糟糕的数据模型,他们总是有充分的理由不改变它。但StackOverflow的目的是帮助人们成为更好的程序员。因此,拥有一个好的数据模型很重要,不仅因为关系完整性至关重要,而且因为它使得编写漂亮干净的SQL更容易。

在你的情况下,SALARY_COMPONENTS_TB比无意义更糟糕。首先,它会强制您在每次需要在查询中使用数据透视表时对其进行编码。这使得查询难以理解并且维护起来更耗时。但是也没有数据完整性。您可以在该表中放置任何内容或删除任何内容;我不保证您({say)salary_component = 'HOUSING'有一行,不保证amount将包含您可以在算术中使用的可预测值。

那么什么是更好的数据模型?使用存储实际值的数字列替换SALARY_TB上的标志列。使用起来更容易,因为它们可能是(应该是)数字列,您可以在算术中使用它而不需要复杂的字符串操作和数据类型转换。好多了。