2016-10-28 41 views
2

我有以下三个表,我试图联合在一起,并创建一个所有桌面和任何人有一个分配给他们的用户名(如果有的话)的概述。我应该用什么样的JOIN加入这些表格?

dbo.Users 
ID Name  Lastname JobTitle 
118 Ryan  Doe  Field Engineer 
119 Jessica Braun  Technical Consultant 
120 Daniel Sous  Web developer 
121 Amy  Amyson  Intern 
.. etc 

dbo.LightDesktops 
ID Model  MACAddress   UserID 
1  HP1234 AA:AA:AA:AA:AA:AA 118 
2  HP1234 BB:BB:BB:BB:BB:BB 121 
3  HP1234 AA:BB:BB:AA:BB:AA NULL 
4  HP1234 BB:AA:BB:AA:AA:BB 124 

dbo.MediumDesktops 
ID Model  MACAddress   UserID 
1 HP12PRO AA:AB:AA:BB:AA:BA 132 
2 HP12PRO BB:BA:AB:BA:BB:AA 119 
3 HP12PRO AA:BA:BA:AB:AA:BA 123 
4 HP12PRO BB:BB:BB:AB:BA:BB 241 

我设法弄清楚如何做到这一点每个类型的桌面,例如LightDesktops:

SELECT * FROM LightDesktops LEFT OUTER JOIN Users ON LightDesktops.UserID = Users.UserID 

,会告诉我他们的资料对台式机的一个很好的概述,以及谁如果有的话有一个。

如果我想有一点用都没有,因此在股票我可以做

SELECT * FROM LightDesktops LEFT OUTER JOIN Users ON LightDesktops.UserID = Users.UserID WHERE LightDesktops.UserID IS NULL 

我怎样才能达到同样的效果光桌面的概述,但包含的信息的两个表我们的桌面?我试图使用一个UNION,但返回了很多重复值。

+1

稍微偏离主题;你有没有考虑将轻型和中型桌面合并成一张桌子?您可以添加一个额外的列来识别哪些是轻/中等。这种方法的好处是它会简化你需要编写的查询。 –

+0

你可以添加一个你希望在输出中看到哪些列的例子吗? –

+2

采取@目的地数据的建议可能是合理的,但也可能无法进行此更改。或者,您可以使用'CREATE VIEW'在一个地方获取连接逻辑,然后在所有后续查询中使用该视图,稍后您可以重构以删除该视图。 –

回答

2

使用UNION带来的轻型和中型桌面表一起作为一个单一的数据集不应该给你重复,除非该表包含重复值的行进行的跨所有您的SELECT条款中的列和您使用UNION ALL如果您知道您的表格具有唯一值,请使用UNION ALL来提高性能。

我将两个表结合起来,公用表表达式(CTE),然后加入用LEFT OUTER JOIN产生的表也可过滤找到的条目不存在匹配WHERE [user].[UserID] IS NULL user表,NB,那将返回已删除用户的桌面表中的孤行行;或者丢弃左外连接,并使用WHERE [desktop].[UserID] IS NULL仅返回没有受到攻击的用户的防打击。

你可以试试下面的代码;

WITH cte_Desktop AS 
(
    SELECT 
     [ID] as [DesktopID], 
     'Light Desktop' as [DekstopType], 
     [Model], 
     [MACAddress], 
     [UserID] 
    FROM [dbo].[LightDesktops] 

    UNION 

    SELECT 
     [ID], 
     'Medium Desktop', 
     [Model], 
     [MACAddress], 
     [UserID] 
    FROM [dbo].[MediumDesktops] 
) 

SELECT 
    [desktop].* 

FROM cte_Desktop AS [desktop] 
LEFT OUTER JOIN [dbo].[Users] AS [user] 
    on [user].[UserID] = [desktop].[UserID] 

WHERE [user].[UserID] IS NULL 
1

尝试

WITH all as (
select model , userid from LightDesktops 
union 
select model , userid from MediumDesktops 
) 

select * FROM all where UserId IS NULL 
+0

你是对的谢谢。 –

1

使用Full join让目前所有用户的报告。它会给你完整的报告。在此之上结果查询用户id为NULL

SELECT U.ID userid, 
     U.NAME, 
     LD.USERID LD_USERID, 
     LD.MODEL LIGHT_MODEL, 
     LD.MACADDRESS LIGHT_MAC, 
     LM.USERID LM_USERID, 
     LM.MODEL MEDIUM_MODEL, 
     LM.MACADDRESS MEDIUM_MAC 
FROM #USERS U 
     FULL OUTER JOIN #LIGHTD LD 
     ON (U.ID = LD.USERID) 
     FULL OUTER JOIN #LIGHTM LM 
     ON (LM.USERID = U.ID) 
1

虽然你可以实现你在一个查询所需要的,它可能是更可支持打破表工会伸到一个观点,让这个逻辑在多个查询中重复使用,还允许在更容易重构以后的日子。

点到destination-data提醒我这一点。

查看

CREATE VIEW [dbo].[Desktops] AS 
(
    SELECT 
     [ID] as [DesktopID], 
     'Light Desktop' as [DekstopType], 
     [Model], 
     [MACAddress], 
     [UserID] 
    FROM [dbo].[LightDesktops] 

    UNION 

    SELECT 
     [ID], 
     'Medium Desktop', 
     [Model], 
     [MACAddress], 
     [UserID] 
    FROM [dbo].[MediumDesktops] 
) 

查询

SELECT 
    [desktop].* 

FROM [dbo].[Desktops] AS [desktop] 
LEFT OUTER JOIN [dbo].[Users] AS [user] 
    on [user].[UserID] = [desktop].[UserID] 

WHERE [user].[UserID] IS NULL 
相关问题