从四个表中检索不同记录的SQL查询

从四个表中检索不同记录的SQL查询,sql,sql-server,Sql,Sql Server,我有四张桌子: 部门(部门ID) 课程(课程ID,部门ID) CourseInstructor(CourseId,InstructorId) 讲师(讲师ID、名、姓、受雇者) 我正在asp.NETMVC上工作。讲师模式是- public class Instructor { public int InstructorId {get; set;} public string FristName {get; set;} public string LastName {get; set

我有四张桌子:

  • 部门(部门ID)
  • 课程(课程ID,部门ID)
  • CourseInstructor(CourseId,InstructorId)
  • 讲师(讲师ID、名、姓、受雇者)
我正在asp.NETMVC上工作。讲师模式是-

public class Instructor
{
  public int InstructorId {get; set;}
  public string FristName {get; set;}
  public string LastName {get; set;}
  public DateTime HireDate {get; set;}
  public string FullName 
  {
     get 
     {
       return FirstName + " " + LastName;
     } 
  }
现在,我需要根据给定的部门ID查找一个部门的所有不同讲师记录

我编写了以下sql查询,但它说-

列名称“InstructorId”不明确

string query=“从讲师中选择讲师ID、MAX(姓氏)、MAX(姓氏)”
+“在CourseInstructor.InstructorId=讲师.InstructorId上左键连接CourseInstructor”
+“在Course.CourseId=CourseInstructor.CourseId上左连接课程”
+“左键加入Department.DepartmentId=Course.DepartmentId上的部门”
+“where Department.DepartmentId=@p0”
+“讲师分组。讲师ID”;
IEnumarable Instructors=db.Database.SqlQuery(query,id);

这里id是给定的部门id。如何解决此问题。

因为指示ID出现在多个表中,SQL Server不知道返回哪个表。有两种方法可以解决这个问题

可以将表名追加到列名之前。所以
选择讲师ID…
变成
选择讲师。讲师ID…

或者,您可以减少表的键入量,并在列名之前添加别名

select 
    i.InstructorId, 
    MAX(i.FirstName), 
    MAX(i.LastName) 
from 
    Instructor AS i
         left outer join CourseInstructor AS ci         on ci.InstructorId  = i.InstructorId 
         left outer join Course on AS c                 on c.CourseId       = ci.CourseId 
         left outer join Department AS d                on d.DepartmentId   = c.DepartmentId 
where 
    d.DepartmentId=@p0 
group by 
    i.InstructorId
;

您需要限定两个或多个选定表中的所有列名:

 string query = "select Instructor.InstructorId, MAX(Instructor.FirstName), MAX(Instructor.LastName) from Instructor "
                + "left join CourseInstructor on CourseInstructor.InstructorId = Instructor.InstructorId "
                + "left join Course on Course.CourseId = CourseInstructor.CourseId "
                + "left join Department on Department.DepartmentId=Course.DepartmentId "
                + "where Department.DepartmentId=@p0 "
                + "group by Instructor.InstructorId";
            IEnumarable<Instructor> Instructors = db.Database.SqlQuery<Instructor>(query, id);
string query=“从讲师中选择讲师.InstructorId、MAX(讲师.姓氏)、MAX(讲师.姓氏)”
+“在CourseInstructor.InstructorId=讲师.InstructorId上左键连接CourseInstructor”
+“在Course.CourseId=CourseInstructor.CourseId上左连接课程”
+“左键加入Department.DepartmentId=Course.DepartmentId上的部门”
+“where Department.DepartmentId=@p0”
+“讲师分组。讲师ID”;
IEnumarable Instructors=db.Database.SqlQuery(query,id);

使用聚合是可疑的。下面是一个使用
exists
的替代方案:

select i.*
from Instructor i
where exists (select 1
              from CourseInstructor ci join 
                   Course c
                   on c.CourseId = ci.CourseId 
              where ci.InstructorId = i.InstructorId and
                    c.DepartmentId = @p0
             );
注:

  • 此版本不需要聚合,因此应该更快
  • 由于id在
    课程
    表中,因此没有必要将
    加入
    部门
  • 左连接是不必要的,因为您的查询需要在
    部门ID
    上进行匹配
  • 表别名使查询更易于编写和读取
  • 完全限定的列名可以防止出现问题
使用下面的查询

string query = "select Instructor.InstructorId, MAX(FirstName), MAX(LastName) from Instructor "
        + "left join CourseInstructor on CourseInstructor.InstructorId = Instructor.InstructorId "
        + "left join Course on Course.CourseId = CourseInstructor.CourseId "
        + "left join Department on Department.DepartmentId=Course.DepartmentId "
        + "where Department.DepartmentId=@p0 "
        + "group by Instructor.InstructorId";

使用限定的列名(即始终使用表别名),您将永远不会遇到此问题。最好是问一个新问题,而不是编辑旧问题。为原始问题提供的答案不再有意义。这会使跟随你的人感到困惑。
string query = "select Instructor.InstructorId, MAX(FirstName), MAX(LastName) from Instructor "
        + "left join CourseInstructor on CourseInstructor.InstructorId = Instructor.InstructorId "
        + "left join Course on Course.CourseId = CourseInstructor.CourseId "
        + "left join Department on Department.DepartmentId=Course.DepartmentId "
        + "where Department.DepartmentId=@p0 "
        + "group by Instructor.InstructorId";