0

现在我必须为搜索页面创建一个查询,该查询取决于具有 30 个表的数据库:

我将用一个例子来描述我的要求:

表 A 和表 B 之间存在关系 -> 一对多关系

如果我们认为表 A 用于学生信息,表 B 用于保存该学生每年的课程。每年只允许选修3门科目,因此结构如下:

表 A: 身份证、学生姓名、电话号码、生日......

表 B: : ID,StudentID,Date,Subject-one,Subject-2,Subject-3

所以学生每年可以选修任何 3 门科目

有效学生的示例:

  StudentID  Sub1  Sub2  Sub3  Year  
  60         Z     (X)    Y      1
  60         L      W     V      2
  60         M      P     Y      3

无效学生的示例:

  StudentID  Sub1  Sub2  Sub3  Year  
  10         Z     (X)    O      1
  10         L      W     V      2
  10         O      P    (x)     3

我希望对我的问题足够清楚

4

2 回答 2

2

我同意表 2 中每个主题的一行会更好(规范化结构实际上总是更好,对 SQL 更友好)的评论。

也就是说,你可以在你的结构中解决它。

SELECT
  studentID
FROM
  table2
WHERE
     sub1 = 'x'
  OR sub2 = 'x'
  OR sub3 = 'x'
GROUP BY
  studentID
HAVING
  COUNT(*) = 1

(这是假设学生不能在同一年两次学习同一科目。)

某些类型的 SQL 可能允许缩短 WHERE 子句...

WHERE
  'x' IN (sub1, sub2, sub3)

然后,您可以通过将其放在子查询中来获取所有学生详细信息...

SELECT
  *
FROM
  table1
INNER JOIN
(
  <put the above query here>
)
  AS lookup
    ON lookup.studentID = table1.studentID

编辑

我不明白你的评论。但是一个替代的(并且可能更普遍的) HAVING 子句可能是..

HAVING
  SUM(CASE WHEN sub1 = 'x' THEN 1 ELSE 0 END +
      CASE WHEN sub2 = 'x' THEN 1 ELSE 0 END +
      CASE WHEN sub3 = 'x' THEN 1 ELSE 0 END)
  = 1
于 2012-10-08T11:26:59.443 回答
0

这样做的一种方法..
对于给定的主题 X,您可以为每个学生运行一个循环,以检查他是否是该主题的有效学生,就像这样。循环内部:

IF(
(SELECT count(1) from TableB where Sub1 = 'X' and StudentID = 60 ) + 
(SELECT count(1) from TableB where Sub2 = 'X' and StudentID = 60 ) + 
(SELECT count(1) from TableB where Sub3 = 'X'and StudentID = 60 ) ) = 1
BEGIN
    INSERT INTO #ValidStudent(...)
END  

您必须将 StudentID 变量代替 60 并在最后..

SELECT * FROM #ValidStudent
于 2012-10-08T11:56:05.847 回答