【问题标题】:Unable to find a solution or workaround无法找到解决方案或解决方法
【发布时间】:2016-10-14 09:30:32
【问题描述】:

SQL Server 2008 及更高版本。

假设我有一个名为“Teachers”的数据库表,其中包含学校教师的详细信息,另一个名为“Schedules”的表包含他们的日程安排。有时,如果我需要在某一天随机分配几个小时给老师/老师,例如当一位老师缺席时,那么另一位老师可以占用该可用时间。

喜欢这里:

Declare @hrs numeric(24, 6) = 3

SELECT T_Code 
FROM Teachers 
LEFT JOIN Schedules S
WHERE (SELECT 8 - ISNULL(SUM(S_HOURS),0) AS AVLHRS
        FROM  Schedules 
        WHERE S_Teacher = S.S_Teacher)  < @hrs
ORDER BY ISNULL(S_HOURS,0), NEWID()

但这里的问题是,只有那些被安排的教师被计算,所以我没有得到所有可用教师的列表。就像假设我有一位甚至没有安排好的新老师也想按照该老师剩余的小时数来订购它。那么这不会显示那个老师,但我也希望看到那个老师。我找不到解决方法。

PS。这不是完整的代码,它会检查许多其他条件,但这是导致问题的唯一条件,我无法显示完整的代码。

【问题讨论】:

  • 我假设新教师没有时间表。如果是这样,那么您将因为 (INNER) JOIN 而将它们过滤掉
  • 由于子查询,即使使用左连接也会被过滤掉

标签: sql sql-server sql-server-2008 isnull correlated-subquery


【解决方案1】:

使用LEFT JOIN这将带来所有教师记录

SELECT T_Code 
FROM Teachers 
LEFT JOIN Schedules S ON Teachers.ID = S.TeacherID
AND (SELECT 8 - ISNULL(SUM(S_HOURS),0) AS AVLHRS
       FROM  Schedules 
       WHERE S_Teacher = S.S_Teacher)  < @hrs
ORDER BY ISNULL(S_HOURS,0), NEWID()

更新:

SELECT T_Code,
       ISNULL(TmpTable.AVLHRS,0)  AVLHRS  
FROM Teachers 
LEFT JOIN Schedules S ON Teachers.ID = S.TeacherID
OUTER APPLY(
   SELECT 8 - ISNULL(SUM(S_HOURS),0) AS AVLHRS
   FROM  Schedules 
   WHERE S_Teacher = S.S_Teacher
)TmpTable
WHERE  TmpTable.AVLHRS < @hrs
ORDER BY AVLHRS

【讨论】:

  • 尝试了左连接,但问题在于子查询而不是连接本身
  • 你试过精确查询吗,根本没有where子句
  • 试过了。谢谢。工作。
  • 但我不知道如何将问题添加为已完成并将回复添加为解决方案
  • 但是我怎样才能按照'AVLHRS'订购呢?
【解决方案2】:

要显示所有教师,无论他们是否有时间表,您都必须使用 LEFT JOIN。 LEFT JOIN 显示左表的所有数据(在您的案例中是教师),即使它在右表中没有值(在您的案例时间表中)。

在您的代码中,如下所示:

SELECT T_Code from Teachers LEFT JOIN Schedules S
WHERE (SELECT 8 - ISNULL(SUM(S_HOURS),0) AS AVLHRS
FROM  Schedules WHERE S_Teacher = S.S_Teacher)  < @hrs
ORDER BY ISNULL(S_HOURS,0), NEWID()

【讨论】:

  • 尝试了左连接,但问题在于子查询而不是连接本身