SQL将两个查询结果合并到一个数据集中

时间:2017-11-26 05:18:50

标签: sql-server report builder

我正在尝试组合两个SQL查询,第一个是

SELECT 
    EAC.Person.FirstName, 
    EAC.Person.Id,
    EAC.Person.LastName, 
    EAC.Person.EmployeeId, 
    EAC.Person.IsDeleted, 
    Controller.Cards.SiteCode, 
    Controller.Cards.CardCode, 
    Controller.Cards.ActivationDate, 
    Controller.Cards.ExpirationDate, 
    Controller.Cards.Status, 
    EAC.[Group].Name
FROM         
    EAC.Person 
INNER JOIN 
    Controller.Cards ON EAC.Person.Id = Controller.Cards.PersonId 
INNER JOIN 
    EAC.GroupPersonMap ON EAC.Person.Id = EAC.GroupPersonMap.PersonId 
INNER JOIN 
    EAC.[Group] ON EAC.GroupPersonMap.GroupId = EAC.[Group].Id

第二个是

SELECT
    IsActive, ActivationDateUTC, ExpirationDateUTC, 
    Sitecode + '-' + Cardcode AS Credential, 'Badge' AS Type, 
    CASE 
       WHEN isActive = 0 
          THEN 'InActive' 
       WHEN ActivationDateUTC > GetUTCDate() 
          THEN 'Pending' 
       WHEN ExpirationDAteUTC < GetUTCDate() 
          THEN 'Expired' 
       ELSE 'Active' 
    END AS Status
FROM
    EAC.Credential
JOIN
    EAC.WiegandCredential ON Credential.ID = WiegandCredential.CredentialId
WHERE 
    PersonID = '32'

我想使用EAC.Person.Id而不是'32'为第一个查询的每个用户运行第二个查询。

我希望在一个数据集中返回所有数据,以便在报表生成器中使用它。

我一整天都在和这个人打架,我希望你们中的一个聪明的家伙可以帮助我。提前谢谢。

2 个答案:

答案 0 :(得分:0)

试试这个;

    select Query1.*, Query2.* from (
    SELECT 
        EAC.Person.FirstName, 
        EAC.Person.Id as PersonId,
        EAC.Person.LastName, 
        EAC.Person.EmployeeId, 
        EAC.Person.IsDeleted, 
        Controller.Cards.SiteCode, 
        Controller.Cards.CardCode, 
        Controller.Cards.ActivationDate, 
        Controller.Cards.ExpirationDate, 
        Controller.Cards.Status, 
        EAC.[Group].Name
    FROM         
        EAC.Person 
    INNER JOIN 
        Controller.Cards ON EAC.Person.Id = Controller.Cards.PersonId 
    INNER JOIN 
        EAC.GroupPersonMap ON EAC.Person.Id = EAC.GroupPersonMap.PersonId 
    INNER JOIN 
        EAC.[Group] ON EAC.GroupPersonMap.GroupId = EAC.[Group].Id) 
        Query1 inner join (SELECT top 100
        IsActive, ActivationDateUTC, ExpirationDateUTC, 
        Sitecode + '-' + Cardcode AS Credential, 'Badge' AS Type, 
        CASE 
           WHEN isActive = 0 
              THEN 'InActive' 
           WHEN ActivationDateUTC > GetUTCDate() 
              THEN 'Pending' 
           WHEN ExpirationDAteUTC < GetUTCDate() 
              THEN 'Expired' 
           ELSE 'Active' 
        END AS Status
    FROM
        EAC.Credential
    JOIN
        EAC.WiegandCredential ON Credential.ID = WiegandCredential.CredentialId
ORDER BY EAC.Credential.ID DESC) Query2 ON Query1.PersonId = Query2.PersonID

只需选择两个查询即可加入它们,例如 Query1 Query2 ,等同于PersonId数据。

答案 1 :(得分:0)

根据评论中的说明,我了解两个数据集之间的联系实际上是PersonID字段,该字段同时存在于EAC.CredentialEAC.Person中;但是,在EAC.Credential中,PersonID存在重复值,而每个PersonID只需要最新值。

有几种方法可以做到这一点,它取决于返回的行数,索引等,但我想也许你正在寻找这样的东西......?

SELECT 
     EAC.Person.FirstName
    ,EAC.Person.Id
    ,EAC.Person.LastName
    ,EAC.Person.EmployeeId
    ,EAC.Person.IsDeleted
    ,Controller.Cards.SiteCode 
    ,Controller.Cards.CardCode
    ,Controller.Cards.ActivationDate
    ,Controller.Cards.ExpirationDate
    ,Controller.Cards.Status
    ,EAC.[Group].Name
    ,X.IsActive
    ,X.ActivationDateUTC
    ,X.ExpirationDateUTC
    ,X.Credential
    ,X.Type
    ,X.Status
FROM EAC.Person 
INNER JOIN Controller.Cards 
    ON EAC.Person.Id = Controller.Cards.PersonId 
INNER JOIN EAC.GroupPersonMap 
    ON EAC.Person.Id = EAC.GroupPersonMap.PersonId 
INNER JOIN EAC.[Group] 
    ON EAC.GroupPersonMap.GroupId = EAC.[Group].Id
CROSS APPLY 
    (
        SELECT TOP 1
             IsActive
            ,ActivationDateUTC
            ,ExpirationDateUTC
            ,Sitecode + '-' + Cardcode AS Credential
            ,'Badge' AS Type
            ,'Status' = 
                CASE
                    WHEN isActive = 0
                        THEN 'InActive'
                    WHEN ActivationDateUTC > GETUTCDATE()
                        THEN 'Pending'
                    WHEN ExpirationDateUTC < GETUTCDATE()
                        THEN 'Expired'
                    ELSE 'Active'
                END 
        FROM EAC.Credential
        INNER JOIN EAC.WiegandCredential
            ON EAC.Credential.ID = EAC.WiegandCredential.CredentialId 
        WHERE EAC.Credential.PersonID = EAC.Person.PersonID
        ORDER BY EAC.Credential.ID DESC
    ) AS X
-- Optionally, you can also add conditions to return specific rows, i.e.:
-- WHERE EAC.Person.PersonID = 32

此选项使用CROSS APPLY,这意味着第一个数据集的每一行都将根据您描述的条件从第二个数据集返回其他值。在此CROSS APPLY中,我根据PersonID(在您的第一个数据集中)和EAC.Person中存在EAC.Credential的事实加入了这两个数据集。然后,我指定每个TOP 1只需要PersonID行,ORDER BY指定我们希望每个{{ID的最新(最高)值PersonID 1}}。

CROSS APPLY别名为“X”,因此在您原来的SELECT中,您现在有几个以X.别名为前缀的值,这意味着您正在使用这些字段从第二个查询并将它们附加到您的原始结果。

CROSS APPLY要求两个数据子集中都存在匹配条目,就像INNER JOIN一样,因此您需要检查并确保相关值存在并正确返回。 / p>

我认为这非常接近你想要的方向。如果没有,请告诉我,我会更新答案。祝你好运!