SQL

时间:2016-05-11 10:37:29

标签: mysql sql database algorithm conditional-statements

首先,先感谢您的帮助。这将是我关于SOF的第一个问题。

我有以下SQL数据库表。

qualificationTable

QualId  studentNo   CourseName   Percentage

1       1           A            91 
2       1           B            81
3       1           C            71
4       1           D            61
5       2           A            91
6       2           B            81
7       2           C            71
8       2           D            59

testTable

TestId  studentNo   testNo  Percentage dateTaken

1       1           1       91         2016-05-02
2       1           2       41         2015-05-02
3       1           3       71         2016-04-02
4       1           1       95         2014-05-02
5       1           2       83         2016-01-02
6       1           3       28         2015-05-02
7       2           1       90         2016-05-02
8       2           2       99         2016-05-02
9       2           3       87         2016-05-02

我分别为课程A,B,C和D指定了最低百分比。我需要搜索学生,达到所有课程的最低标准。

部分-2: 该学生还应该与testTable中的标准(三个测试的单独指定的最小百分比1,2和3)相匹配。

换句话说,如果学生符合所有课程单独指定的最低标准(百分比),则应选择他。现在,对于testTable来说,那个特定的学生(在qualifiedTable中被选中)应该具有为testNo列中的三个测试(1,2和3)单独指定的最小标准(百分比)。

修改

我已经更新了testTable,现在有一个特定学生的多个测试。我需要检查学生是否满足所有3个测试所规定的最低要求百分比,但是,只有最近参加的每个测试(1,2和3)的测试都应该计算。如果学生不符合最近一次考试规定的最低标准,则不应包括在内。

测试用例:

要求的最低资格百分比:

  

课程A:90课程B:80课程C:70课程D:60

所需的最低测试百分比:

  

测试1:90测试2:80测试3:70

预期输出

studentNo

1

干杯

2 个答案:

答案 0 :(得分:0)

First find students who does not qualify the minimum percentage.

select distinct studentNo
from stdqualificationmaster
where case when CourseName='A' and  Percentage<90 then 'F' 
           when CourseName='B' and  Percentage<80 then 'F'
           when CourseName='C' and  Percentage<70 then 'F'
           when CourseName='D' and  Percentage<60 then 'F'
      end='F'

As a second step we can use above unqualified students result set as filter for required result set.

select * from stdqualificationmaster where studentNo not in 
(    select distinct studentNo
from stdqualificationmaster
where case when CourseName='A' and  Percentage<90 then 'F' 
           when CourseName='B' and  Percentage<80 then 'F'
           when CourseName='C' and  Percentage<70 then 'F'
           when CourseName='D' and  Percentage<60 then 'F'
      end='F')

答案 1 :(得分:0)

我只是想出了你的样本数据和测试用例

  

要求的最低资格百分比:

     
    

课程A:90课程B:80课程C:70课程D:60

  
     

所需的最低测试百分比:

     
    

测试1:90测试2:80测试3:70

  

试试这个,可能对你有帮助;)

SQL Fiddle

MySQL架构

CREATE TABLE qualificationTable
    (`QualId` int, `studentNo` int, `CourseName` varchar(1), `Percentage` int)
;

INSERT INTO qualificationTable
    (`QualId`, `studentNo`, `CourseName`, `Percentage`)
VALUES
    (1, 1, 'A', 91),
    (2, 1, 'B', 81),
    (3, 1, 'C', 71),
    (4, 1, 'D', 61),
    (5, 2, 'A', 91),
    (6, 2, 'B', 81),
    (7, 2, 'C', 71),
    (8, 2, 'D', 50)
;


CREATE TABLE testTable
    (`TestId` int, `studentNo` int, `testNo` int, `Percentage` int)
;

INSERT INTO testTable
    (`TestId`, `studentNo`, `testNo`, `Percentage`)
VALUES
    (1, 1, 1, 91),
    (2, 1, 2, 81),
    (3, 1, 3, 71),
    (4, 2, 1, 80),
    (5, 2, 2, 99),
    (6, 2, 3, 87)
;

查询1

select t1.studentNo
from 
(
  select studentNo from qualificationTable
  where (CourseName = 'A' and Percentage >= 90)
  or (CourseName = 'B' and Percentage >= 80)
  or (CourseName = 'C' and Percentage >= 70)
  or (CourseName = 'D' and Percentage >= 60)
  group by studentNo
  having count(1) = 4
) t1 join
( select studentNo from testTable
  where (testNo = '1' and Percentage >= 90)
  or (testNo = '2' and Percentage >= 80)
  or (testNo = '3' and Percentage >= 70)
  group by studentNo
  having count(1) = 3
) t2 on t1.studentNo = t2.studentNo

我只选择t1这两个子查询中的一个来解释它是如何工作的:

  • GROUP BY可以为我们提供这样的结果,
    | studentNo |
    |-----------|
    |         1 |
    |         2 |
  • COUNT会得到每组的总数,对于你的样本数据,studentNo(1)是4,studentNo(2)也是4,但我们这里也有where子句,所以按这些标准,我们可以找到匹配的记录,
    (1, 1, 'A', 91),
    (2, 1, 'B', 81),
    (3, 1, 'C', 71),
    (4, 1, 'D', 61),
    (5, 2, 'A', 91),
    (6, 2, 'B', 81),
    (7, 2, 'C', 71)
  • 这意味着COUNT会给我们studentNo(1)到4,studentNo(2)到3,所以当mysql运行having count(1) = 4时,这个子查询只返回我们studentNo(1)

子查询t2的工作方式与此类似,当通过studentNo加入这两个子查询时,它将返回您预期的结果。

<强> Results

| studentNo |
|-----------|
|         1 |

<强> 编辑:

select t1.studentNo
from 
(
  select studentNo from qualificationTable
  where (CourseName = 'A' and Percentage >= 90)
  or (CourseName = 'B' and Percentage >= 80)
  or (CourseName = 'C' and Percentage >= 70)
  or (CourseName = 'D' and Percentage >= 60)
  group by studentNo
  having count(1) = 4
) t1 join
( select studentNo
  from (
      select *
      from testTable
      where (testNo, dateTaken) in (
          select testNo, Max(dateTaken) from testTable group by testNo
      )
  ) tmp
  where (testNo = '1' and Percentage >= 90)
  or (testNo = '2' and Percentage >= 80)
  or (testNo = '3' and Percentage >= 70)
  group by studentNo
  having count(1) = 3
) t2 on t1.studentNo = t2.studentNo