加入多个表?可选?条件并得到所有结果

时间:2016-09-08 19:27:18

标签: sql sql-server sql-server-2008 join

使用SQL 2008 R2

我无法完成表连接。我想我只是缺少一些简单的东西。我需要加入三个表(CMS,DB,备份)并获取所有重叠以及缺少项目的完整列表。不幸的是,其中两个表没有简单的条件来进行连接。

条件:
1:每个表都可以有一行不匹配其他表
2:备份连接Server_Name和Backups.Save_Set就像DB.Instance_Name或Backups.Save_Set就像'ALL'一样 3:CMS加入Server_Name,CMS.Name就像DB.Name

从下面我的查询结果中可以看出,我很接近,但并不完全存在。我似乎无法正确连接两个顶行或我的结果,因为它们与条件不匹配。

非常感谢任何帮助。我似乎无法找到我所缺少的东西。

在底部创建/填充脚本

表:DB

ID    Server_Name      Instance_Name        Name        Company_Code
----- ---------------- -------------------- ----------- --------------------
1     Server11         MSSQLSERVER          PUB         14
2     Server11         MSSQLSERVER          Test        10
3     Server11         MSSQLSERVER          fasys       14
4     Server12         MSSQLSERVER          PROD        14
5     Server21         MSSQLSERVER          PROD        24

表:CMS

ID          Name                     Server_Name          Responsible
----------- ------------------------ -------------------- ---------------
1           Site1 SQL DB PUB         Server11             PDM
2           Site1 SQL DB Test        Server11             RH
3           Site1 SQL DB PROD        Server12             PDM
4           Site2 SQL DB PROD        Server21             SP
5           Site2 SQL DB Test        Server21             PDM

表:备份

ID     Server_Name     Backup_Retention     Save_Set
------ --------------- -------------------- ---------------------
1      Server11        3Month               MSSQL$MSSQLSERVER
2      Server11        3Month               MSSQL$ECS
3      Server12        3Month               ALL
4      Server22        3Month               ALL

我接近:

SELECT AllNames.Server_Name
      ,CMS.Name
      ,CMS.Responsible
      ,DB.Instance_Name
      ,DB.Name
      ,DB.Company_Code
      ,B.Backup_Retention
      ,B.Save_Set
FROM (SELECT Server_Name FROM CMS
    UNION
    SELECT Server_Name FROM DB
    UNION
    SELECT Server_Name FROM Backups) AllNames
LEFT JOIN DB ON AllNames.Server_Name = DB.Server_Name
FULL JOIN Backups B ON AllNames.Server_Name = B.Server_Name
                                  AND ((B.Save_Set LIKE '%' + DB.Instance_Name OR DB.Instance_Name IS NULL) OR B.Save_Set LIKE 'ALL')
FULL JOIN CMS ON AllNames.Server_Name = CMS.Server_Name
                                 AND CMS.Name LIKE '%' + DB.Name
ORDER BY AllNames.Server_Name ASC

返回:

Server_Name   Name                Responsible   Instance_Name   Name    Company_Code   Backup_Retention   Save_Set
------------- ------------------- ------------- --------------- ------- -------------- ------------------ -------------------
NULL          NULL                NULL          NULL            NULL    NULL           3Month             MSSQL$ECS
NULL          Site2 SQL DB Test   PDM           NULL            NULL    NULL           NULL               NULL
Server11      Site1 SQL DB PUB    PDM           MSSQLSERVER     PUB     14             3Month             MSSQL$MSSQLSERVER
Server11      Site1 SQL DB Test   RH            MSSQLSERVER     Test    10             3Month             MSSQL$MSSQLSERVER
Server11      NULL                NULL          MSSQLSERVER     fasys   14             3Month             MSSQL$MSSQLSERVER
Server12      Site1 SQL DB PROD   PDM           MSSQLSERVER     PROD    14             3Month             ALL
Server21      Site2 SQL DB PROD   SP            MSSQLSERVER     PROD    24             NULL               NULL
Server22      NULL                NULL          NULL            NULL    NULL           3Month             ALL

我想看到的内容(不要担心列标题):

Server_Name   CMS.Name            CMS.Responsible  DB.Instance_Name  DB.Name  DB.Company_Code  Backups.Backup_Retention  Backups.Save_Set
------------  ------------------  ---------------- ----------------- -------- ---------------- ------------------------- -----------------
Server11      Site1 SQL DB PUB    PDM              MSSQLSERVER       PUB      14               3Month                    MSSQL$MSSQLSERVER
Server11      Site1 SQL DB Test   RH               MSSQLSERVER       Test     10               3Month                    MSSQL$MSSQLSERVER
Server11      NULL                NULL             MSSQLSERVER       fasys    14               3Month                    MSSQL$MSSQLSERVER
Server11      NULL                NULL             NULL              NULL     NULL             3Month                    MSSQL$ECS
Server12      Site1 SQL DB PROD   PDM              MSSQLSERVER       PROD     14               3Month                    ALL
Server21      Site2 SQL DB PROD   SP               MSSQLSERVER       PROD     24               NULL                      NULL
Server21      Site2 SQL DB Test   PDM              NULL              NULL     NULL             NULL                      NULL
Server22      NULL                NULL             NULL              NULL     NULL             3Month                    ALL

创建/填充:

CREATE TABLE CMS(
   ID int  NOT NULL IDENTITY(1, 1),
   Name nvarchar(60)  NOT NULL,
   Server_Name nvarchar(20)  NOT NULL,
   Responsible nvarchar(20)  NULL
   CONSTRAINT CMS_DB_Audit_pk PRIMARY KEY  (ID)
);

CREATE TABLE DB(
   ID int  NOT NULL IDENTITY(1, 1),
   Server_Name nvarchar(20)  NOT NULL,
   Instance_Name nvarchar(20) NOT NULL,
   Name nvarchar(60)  NOT NULL,
   Company_Code nvarchar(20)  NULL
   CONSTRAINT DB_pk PRIMARY KEY  (ID)
);

CREATE TABLE Backups (
   ID int  NOT NULL IDENTITY(1, 1),
   Server_Name nvarchar(30)  NOT NULL,
   Backup_Retention nvarchar(20)  NOT NULL,
   Save_Set nvarchar(max)  NOT NULL,
   CONSTRAINT Backups_pk PRIMARY KEY  (ID)
);

INSERT INTO CMS
VALUES 
('Site1 SQL DB PUB','Server11','PDM'),
('Site1 SQL DB Test','Server11','RH'),
('Site1 SQL DB PROD','Server12','PDM'),
('Site2 SQL DB PROD','Server21','SP'),
('Site2 SQL DB Test','Server21','PDM');

INSERT INTO DB
VALUES 
('Server11','MSSQLSERVER','PUB',14),
('Server11','MSSQLSERVER','Test',10),
('Server11','MSSQLSERVER','fasys',14),
('Server12','MSSQLSERVER','PROD',14),
('Server21','MSSQLSERVER','PROD',24);

INSERT INTO Backups
VALUES 
('Server11','3Month','MSSQL$MSSQLSERVER'),
('Server11','3Month','MSSQL$ECS'),
('Server12','3Month','ALL'),
('Server22','3Month','ALL');

2 个答案:

答案 0 :(得分:0)

你非常接近:

试试这个:

WITH AllServers AS
(
    SELECT DISTINCT Server_Name FROM DB 
    UNION SELECT Server_Name FROM CMS
    UNION SELECT Server_Name FROM Backups
)
SELECT COALESCE(AllServers.Server_Name,DB.Server_Name,CMS.Server_Name,Backups.Server_Name) AS Server_Name
      ,CMS.Name AS CMS_Name
      ,CMS.Responsible AS CMS_Responsible
      ,DB.Instance_Name AS DB_InstanceName
      ,DB.Name AS [DB_Name]
      ,DB.Company_Code AS DB_CompanyCode
      ,Backups.Backup_Retention
      ,Backups.Save_Set
FROM AllServers
FULL OUTER JOIN DB ON AllServers.Server_Name=DB.Server_Name 
FULL OUTER JOIN Backups ON AllServers.Server_Name=Backups.Server_Name AND (Backups.Save_Set LIKE '%' + DB.Instance_Name OR Backups.Save_Set='ALL')
FULL OUTER JOIN CMS ON AllServers.Server_Name=CMS.Server_Name AND CMS.Name LIKE '%' + DB.Name
ORDER BY COALESCE(AllServers.Server_Name,DB.Server_Name,CMS.Server_Name,Backups.Server_Name)

更新:试图找到差异......

我认为,如果您只是在第一行使用我的COALESCE(AllNames.Server_Name,DB.Server_Name,CMS.Server_Name,B.Server_Name)并将其作为ORDER BY,那么您的解决方案就非常完美......

答案 1 :(得分:0)

这对你有用吗?

SELECT coalesce(DB.Server_Name, b.Server_Name, CMS.Server_Name) Server_Name
      ,CMS.Name
      ,CMS.Responsible
      ,DB.Instance_Name
      ,DB.Name
      ,DB.Company_Code
      ,B.Backup_Retention
      ,B.Save_Set
FROM #DB DB --ON AllNames.Server_Name = DB.Server_Name
FULL JOIN #Backups B ON DB.Server_Name = B.Server_Name
                                  AND ((B.Save_Set LIKE '%' + DB.Instance_Name /*OR DB.Instance_Name IS NULL*/) OR B.Save_Set LIKE 'ALL')
FULL JOIN #CMS CMS ON DB.Server_Name = CMS.Server_Name
                                 AND CMS.Name LIKE '%' + DB.Name
ORDER BY coalesce(DB.Server_Name, b.Server_Name, CMS.Server_Name) ASC

它将结果作为

Server_Name Name    Responsible Instance_Name   Name    Company_Code    Backup_Retention    Save_Set
Server11    Site1 SQL DB PUB    PDM MSSQLSERVER PUB 14  3Month  MSSQL$MSSQLSERVER
Server11    Site1 SQL DB Test   RH  MSSQLSERVER Test    10  3Month  MSSQL$MSSQLSERVER
Server11    NULL    NULL    MSSQLSERVER fasys   14  3Month  MSSQL$MSSQLSERVER
Server11    NULL    NULL    NULL    NULL    NULL    3Month  MSSQL$ECS
Server12    Site1 SQL DB PROD   PDM MSSQLSERVER PROD    14  3Month  ALL
Server21    Site2 SQL DB PROD   SP  MSSQLSERVER PROD    24  NULL    NULL
Server21    Site2 SQL DB Test   PDM NULL    NULL    NULL    NULL    NULL
Server22    NULL    NULL    NULL    NULL    NULL    3Month  ALL