将多个视图连接在一起时,我得到了重复的记录,但看不到解决方法

When Joining multiple views together I get duplicate records and I can't see a way out of it

我有一个日志 table,其中记录了部门内服务经理、资源经理和员工对 "Slots" 的分配。我知道插槽逻辑很复杂,但它以这种方式运行是一个特定的要求。

因为我有多个 ID(ResourceManagerID、EmployeeID 和 ServiceManagerID),所有外键都指向此日志中的 EmployeeID table 我必须创建多个视图,然后将它们连接在一起以获取数据正确的格式。我已经完成了其中一个名为 "VMasterData" 的视图,我将这个视图基于那个视图,但我似乎没有获得相同的功能。

下面是插槽table:

GO
CREATE TABLE [HeadCount_Ver01].[dbo].Slots(
    SlotID                          INTEGER         IDENTITY        NOT NULL

    PRIMARY KEY(SlotID)
);
GO

下面是日志的 Table 结构 table:

GO
     CREATE TABLE [HeadCount_Ver01].[dbo].DepartmentSlotsLog(
    DepartmentID                    INTEGER                         NOT NULL,
    SlotID                          INTEGER                         NOT NULL,
    EmployeeID                      INTEGER                             NULL,
    ResourceManagerID               INTEGER                             NULL,
    ServiceManagerID                INTEGER                             NULL,
    LogDate                         DATETIME                        NOT NULL

    PRIMARY KEY(DepartmentID, SlotID, LogDate)
);
GO

下面是部门Table

GO
CREATE TABLE [HeadCount_Ver01].[dbo].Departments(
    DepartmentID                    INTEGER         IDENTITY        NOT NULL,
    DepartmentName                  VARCHAR(50)                     NOT NULL,
    AllocatedSlots                  INTEGER                         NOT NULL

    PRIMARY KEY(DepartmentID)
);
GO

下面是员工Table。

GO
CREATE TABLE [HeadCount_Ver01].[dbo].Employees(
    EmployeeID                      INTEGER                         NOT NULL,
    FirstName                       VARCHAR(50)                     NOT NULL,
    MiddleName                      VARCHAR(50)                     NOT NULL,
    LastName                        VARCHAR(50)                     NOT NULL,
    EmployeeType                    INTEGER                         NOT NULL,
    EmployeeStatus                  INTEGER                         NOT NULL,
    EmployeeLevel                   INTEGER                         NOT NULL,
    EmployeeRole                    INTEGER                         NOT NULL,
    Proactive                       BIT                             NOT NULL

    PRIMARY KEY(EmployeeID)
);
GO

以下是员工槽日志数据:

CREATE VIEW VEmployeeSlotsLogData

AS
SELECT 
    D.DepartmentID                          AS DepartmentID,
    DSL.SlotID                              AS SlotID,
    D.DepartmentName                        AS DepartmentName,
    DSL.ResourceManagerID                   AS ResourceManagerID,
    DSL.ServiceManagerID                        AS ServiceManagerID,
    E.EmployeeID                            AS EmployeeID,
    E.LastName + ', ' + E.FirstName         AS EmployeeFullName,
    E.EmployeeRole                          AS EmployeeRole,
    E.EmployeeLevel                         AS EmployeeRoleLevel


FROM

    Departments         AS  D
        JOIN DepartmentSlotsLog     AS  DSL
            ON D.DepartmentID = DSL.DepartmentID

        LEFT JOIN Employees         AS  E
            ON DSL.EmployeeID = E.EmployeeID

下面是资源管理器视图:

CREATE VIEW VResourceManagerLogData

AS
SELECT 
    D.DepartmentID                          AS DepartmentID,
    DSL.SlotID                              AS SlotID,
    D.DepartmentName                        AS DepartmentName,
    DSL.ResourceManagerID                   AS ResourceManagerID,
    E.LastName + ', ' + E.FirstName         AS EmployeeFullName,
    E.EmployeeRole                          AS EmployeeRole,
    E.EmployeeLevel                         AS EmployeeRoleLevel,
    CONVERT(VARCHAR(50), DSL.LogDate, 107)  AS RecordDate

FROM

    Departments         AS  D
        LEFT JOIN DepartmentSlotsLog        AS  DSL
            ON D.DepartmentID = DSL.DepartmentID

        LEFT JOIN Employees         AS  E
            ON DSL.ResourceManagerID = E.EmployeeID

下面是服务管理器视图

CREATE VIEW VServiceManagerLogData

AS
SELECT 
    D.DepartmentID                          AS DepartmentID,
    DSL.SlotID                              AS SlotID,
    D.DepartmentName                        AS DepartmentName,
    DSL.ServiceManagerID                    AS ServiceManagerID,
    E.LastName + ', ' + E.FirstName         AS EmployeeFullName,
    E.EmployeeRole                          AS EmployeeRole,
    E.EmployeeLevel                         AS EmployeeRoleLevel,
    CONVERT(VARCHAR(50), DSL.LogDate, 107)  AS RecordDate


FROM

    Departments         AS  D
        LEFT JOIN DepartmentSlotsLog        AS  DSL
            ON D.DepartmentID = DSL.DepartmentID

        LEFT JOIN Employees         AS  E
            ON DSL.ServiceManagerID = E.EmployeeID

下面是我正在尝试创建的 MastLogView:

CREATE VIEW VMasterLogData

AS
SELECT 
    VESLD.DepartmentID                  AS DepartmentID,
    VESLD.DepartmentName                AS DepartmentName,
    VESLD.SlotID                        AS SlotID,
    VESLD.EmployeeID                    AS EmployeeID,
    VESLD.EmployeeFullName              AS EmployeeFullName,
    VESLD.EmployeeRole                  AS EmployeeRole,
    VESLD.EmployeeRoleLevel             AS EmployeeRoleLevel,
    VESLD.ResourceManagerID             AS RMID,
    VRMLD.EmployeeFullName              AS RMFullName,
    VESLD.ServiceManagerID              AS SMID,
    VSMLD.EmployeeFullName              AS SMFullName,
    VSMLD.RecordDate                    AS RecordDate

FROM

    VEmployeeSlotsLogData  AS VESLD
        LEFT JOIN VResourceManagerLogData   AS VRMLD
        ON VESLD.ResourceManagerID = VRMLD.ResourceManagerID
       AND VESLD.SlotID            = VRMLD.SlotID

        LEFT JOIN VServiceManagerLogData    AS VSMLD
        ON VESLD.ServiceManagerID = VSMLD.ServiceManagerID
       AND VESLD.SlotID           = VSMLD.SlotID

下面的第二个屏幕截图是未合并格式的记录。我得到 3360 条记录,这是正确的。

第一个屏幕截图是我 运行 之后的主日志,请注意,一旦添加了资源管理器或服务管理器,条目就会加倍,我有点理解为什么会这样会发生,但我不知道如何阻止它。我用同样的方法让它在不同的日志 table 上工作,但这次没有骰子。我收到了 4000 多条记录,这有点太多了。

* 编辑删除的屏幕截图 *

感谢任何帮助。

所以在对我的大脑进行精神压力之后,我记得大约 sub-queries。这是我简单而快速的解决方案。

CREATE VIEW VMasterLogData

AS

SELECT
   DSL.DepartmentID,
   DSL.EmployeeID,
   (SELECT E.LastName + ', ' + E.FirstName AS FullName FROM Employees AS E WHERE E.EmployeeID = DSL.EmployeeID) AS EmployeeName,
   DSL.ResourceManagerID,
   (SELECT E.LastName + ', ' + E.FirstName AS FullName FROM Employees AS E WHERE E.EmployeeID = DSL.ResourceManagerID) AS RMName,
   DSL.ServiceManagerID,
   (SELECT E.LastName + ', ' + E.FirstName AS FullName FROM Employees AS E WHERE E.EmployeeID = DSL.ServiceManagerID) AS SMName,
   DSL.LogDate

FROM 
   DepartmentSlotsLog  AS DSL