【问题标题】:A Very Difficult Query I Need to Preform In Order to Create My Model为了创建我的模型,我需要执行一个非常困难的查询
【发布时间】:2019-01-31 10:17:04
【问题描述】:

所以在我的项目中,我需要访问一个名为“日期”的表。表“日期”包含以下内容:

ClassID | TeacherID | StudentID | DateInfo | Status | DateID

对于除 DateID 之外的任何 ID,我需要创建一个连接到 Dates 模型的模型。 另一个重要的信息是我有一个名为“用户”的表,其中 2 个表来自“用户”、“学生”和“教师”。

我的问题:因为我需要学生和老师 同样的记录,我需要从数据库中请求用户的信息 关于他们两个在同一个查询中。我不能这样做,因为我 不知道如何定义学生的信息不同于 教师信息。

用户表:

UserID | Name | LastName | Password | Status | Role 

教师表:

TeacherID | ClassID

学生桌:

StudentID | YearAndClass

我正在尝试创建的查询:

SELECT
IF(Users.Role == 0(Student Role))
  Users.Name as sName, ....
ELSE IF(Users.Role == 1(Teacher Role))
  Users.Name as tName, ....  
FROM Dates, Users, Students, Teachers

我知道这行不通,但我不确定我还能如何描述它。

提前致谢!

【问题讨论】:

  • 您当前的设计似乎没有被规范化,因此您应该先解决这个问题,然后再做其他任何事情。此外,您可能希望在您的问题中添加一些示例数据。
  • 用case语句找出角色并使用inner join来获取名字。不要使用其他列来显示教师姓名和学生姓名不同。
  • 我认为数据库结构需要更多的工作,最大的问题是如果 ID 与明确其角色的表相关,为什么要在 User 表中使用 [Role] 字段?我还建议正确加入表而不使用逗号。如果您有时间在互联网上搜索,您会发现一些有趣的读物,例如:stackoverflow.com/questions/5294311/…
  • @ChrisCarroll 这不是数据库的完整版本。另外,老师也可以是父母,所以我需要识别。

标签: sql sql-server


【解决方案1】:

根据我对您问题的评论,我仍然认为您应该返回并稍微修改您的结构,您似乎大部分时间都在那里,但最好在使用它之前让任何流程的基础正确。

也就是说,据我了解,您希望将用户名放在 1 个列表中,但可以通过他们的角色来区分。以下应该可以工作。

我已经添加了 UserID 和 Role 字段,以便您可以根据您的数据检查它们,看看它是否按预期工作。

    SELECT
     CASE   WHEN d.Role = 'Teacher Role' THEN ut.UserID
            WHEN d.Role = 'Student Role' THEN us.UserID
            ELSE ''
        END AS UserID
    ,CASE   WHEN d.Role = 'Teacher Role' THEN ut.Name
            WHEN d.Role = 'Student Role' THEN us.Name
            ELSE ''
        END AS UserName
    ,d.Role
    FROM Dates d
    LEFT JOIN Users ut ON d.TeacherID = ut.UserID
    INNER JOIN Teachers t ON ut.UserID = t.TeacherID
    LEFT JOIN Users us ON d.StudentID = us.UserID
    INNER JOIN Students s ON us.UserID = s.StudentID

或者可能是以下(未经测试);

    SELECT
     CASE   WHEN d.Role = 'Teacher Role' THEN ut.UserID
            WHEN d.Role = 'Student Role' THEN us.UserID
            ELSE ''
        END AS UserID
    ,CASE   WHEN d.Role = 'Teacher Role' THEN ut.Name
            WHEN d.Role = 'Student Role' THEN us.Name
            ELSE ''
        END AS UserName
    ,d.Role
    FROM Dates d
    LEFT JOIN Users ut ON d.TeacherID = ut.UserID AND ut.UserID IN (SELECT DISTINCT TeacherID FROM Teachers)
    LEFT JOIN Users us ON d.StudentID = us.UserID AND us.UserID IN (SELECT DISTINCT StudentID FROM Students)

【讨论】:

  • 小心依赖于来自左连接的列的内连接。
  • @EzLo 左连接有什么作用?
  • 我在“日期”中没有角色栏,我该如何修改您的答案?
  • 那是我的错,误读了您的表格。但是你能给出完整的预期输出吗?此刻你有 SELECT teacherName ..... , StudentName ...... 你能用所有必需的字段替换 ..... 吗?在不知道预期输出的情况下,很难知道我是否需要对项目进行分组,或者即使加入或联合是最好的。谢谢
【解决方案2】:

正如我所说,我正在做一个项目。我的项目是一个管理学校家长会的系统。 这些是我的表格、关系等

我的目标是在我的 API 中创建一个“getAllDates”函数。

在我的数据库中,日期表是所有“教师-家长会议”信息的存储位置。因此,我的 Dates 表包含一堆外键,即 在我的 API 代码中被转换为 Dates 模型中其他模型的实例,如下所示:

namespace ProjAPI.Models
{
    public class Date
    {
        public DateTime DateInfo;
        public Student Student;
        public Teacher Teacher;
        public Classroom Classroom;
        public int Status, Id;
    }
}

正如你想象的那样,每个实例都有自己的属性,我需要提供给他的属性。那是我的问题开始的时候。

那么让我们看看其他模型:

用户模型

namespace ProjAPI.Models
{
    public class User
    {
        public string Name, LastName, Address, Phone, Pass, Email, Id;
        public int Role, Status;
    }
}

学生模型

namespace ProjAPI.Models
{
    public class Student : User
    {
        public string YearAndClass;
    }
}

教师模式

namespace ProjAPI.Models
{
    public class Teacher : User
    {
        public Classroom Classroom;
    }
}

课堂模式

namespace ProjAPI.Models
{
    public class Classroom
    {
        public Building Building;
        public string Id;
        public string Name;
    }
}

建筑模型

namespace ProjAPI.Models
{
    public class Building
    {
        public string Id;
        public int RoomNum;
    }
}

所以,我需要一个查询: 1.获取老师和学生的所有信息,并重命名列 所以我可以在代码中访问它们。 2. 获取有关班级的所有信息,并将它们区分开来,以便我可以分别访问每个班级。 3. 获取有关日期的所有信息。

为了解决这个问题,我在查询中创建了临时表:

(
    SELECT 
        Classes.ClassID as cID, Classes.ClassName as cName, 
        Buildings.BuildingID as bID, Buildings.RoomNum 
    FROM 
        Classes 
    FULL OUTER JOIN 
        Buildings 
    on 
        Classes.BuildingID  = Buildings.BuildingID
) as cb,

cb 是一个临时表,代表我的 Dates 表中的类。

(
    SELECT 
        Buildings.RoomNum as tcRoomNum,
        Classes.ClassID as tcID, Classes.BuildingID as tcbID,
        Classes.ClassName,ut.*
    FROM 
        Classes,Buildings,
        (
            SELECT 
                UserID as tID, Name as tName, LastName as tLastName,
                Status as tStatus, Role as tRole, Phone as tPhone,
                Email as tEmail, Address as tAddress,Password as tPassword,
                 ClassID as clID
            FROM 
                Users 
            LEFT JOIN 
                Teachers 
            ON 
                UserID = TeacherID
        ) as ut 
    WHERE 
        ut.clID=Classes.ClassID 
        AND Classes.BuildingID = Buildings.BuildingID
) as utcb,

utcb 是一个临时表,代表我的 Dates 表中的老师。

(
    SELECT 
        UserID as sID, Name as sName, LastName as sLastName,
        Status as sStatus, Role as sRole, Phone as sPhone,
        Email as sEmail, Address as sAddress, Password as sPassword,
         YearAndClass
     FROM 
     Users 
     LEFT JOIN 
        Students 
     ON 
        UserID = StudentID
) as us

us 是一个临时表,用于代表我的 Dates 表中的学生。

现在,当我创建临时表时,我可以访问它们并正确过滤:

SELECT 
    DateInfo,DateID,Dates.Status as dStatus,us.*,utcb.*,cb.* 
FROM 
    Dates,cb,utcb,us
WHERE
Dates.StudentID = us.sID 
AND Dates.TeacherID = utcb.tID
AND Dates.ClassID = cb.cID

我知道我做得不好而且效率低下,但我一个人做这件事很艰难,我为自己感到骄傲。 如果有人对升级此查询有任何建议,请随时告诉我。

【讨论】:

    猜你喜欢
    • 2015-01-30
    • 2021-03-27
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2013-01-18
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多