SQL连接多个表

时间:2013-02-17 06:29:02

标签: sql database-design left-join inner-join

  • ClassId(PK)
  • 类名
  • ClassCapacity

批量

  • BatchId(PK)
  • BatchName
  • 尺寸
  • 状态{NotStarted,Enrolled,Completed}

BatchClass

  • BatchClassId(PK)
  • BatchId(FK)
  • ClassId(FK)
  • NoOfStudents

关系

  • 一个类具有最大容量,因此一个批处理可以有很多类,但是在给定时间,只能为一个状态为=已注册的批处理分配一个类(这将从应用程序端验证)

我希望将当前未分配的所有课程分配给状态不等于已注册

的批次

这就是我试过的,

SELECT C.* 
FROM Class C 
LEFT JOIN (
    Batch B 
      INNER JOIN BatchClass BC 
        ON B.BatchId = BC.BatchId
    ) ON C.ClassId = BC.ClassId 
WHERE B.Status <> "Enrolled";

即使我尝试WHERE B.Status =“Enrolled”,它也会给出所有已注册批次的类。我想要的是从上面的SQL不适合我的Opposite。

我不确定我的设计或SQL语句是否有问题。请帮忙。提前谢谢。

3 个答案:

答案 0 :(得分:1)

这应该可以正常工作:

SELECT DISTINCT C.* 
FROM Class AS C 
INNER JOIN BatchClass AS BC ON C.ClassID = BC.ClassID
INNER JOIN Batch      AS B  ON B.BatchId = BC.BatchId 
WHERE B.Status <> 'Enrolled';

<击> SQL Fiddle Demo


更新1

请改为尝试:

SELECT C.*
FROM Class AS C 
WHERE c.ClassID NOT IN(SELECT bc.ClassID
                       FROM BatchClass bc
                       INNER JOIN Batch b ON B.BatchId = BC.BatchId
                       WHERE b.status = 'Enrolled');

Updated SQL Fiddle Demo

答案 1 :(得分:1)

非常感谢每一个人。我找到了解决这个问题的方法。非常感谢Mohmoud Gamal。该演示有很多帮助。

这是解决方案。

SELECT DISTINCT C.* 
FROM Class AS C
WHERE C.ClassId NOT IN
(SELECT BC.ClassId FROM BatchClass AS BC 
INNER JOIN Batch AS B ON  B.BatchId = BC.BatchId 
WHERE B.Status = 'Enrolled');

以这种方式,它返回当前未分配给已注册批次的所有类。 SQL Fiddle Demo更清楚地说明了这一点。

答案 2 :(得分:0)

我认为您的结果会错过与任何批次无关的类。

SELECT C.* FROM Class C 
LEFT JOIN (    
    Batch B
    INNER JOIN BatchClass BC 
    ON B.BatchId = BC.BatchId
) ON C.ClassId = BC.ClassId
WHERE B.Status <> "Enrolled" OR
      B.Status is null;