如何有条件地加入

时间:2018-07-20 10:39:35

标签: sql sql-server tsql left-join inner-join

我有两个桌子。

“ mw_user”表如下所示(正在测试中,我只有4条记录。) user table image

我也有一个由应用程序填充的“ mw_user_selections”表。为了测试,我在这里有两个记录,但最终会有更多记录出现在这里。

user_selection_criteria table image

现在我要完成的工作是将用户分组到特定的选择mw_user_selections组中。因此,如果您查看表格,我可以看到对于Rule1,仅指定了RANK_CODE和SUB_SERVICE_LINE_CODE,因此仅标记了强匹配项。 对于第二个Rule2,我填充了COUNTRY_CODE和SUB_SERVICE_LINE_CODE。因此,只有Mathew Perry和Dwane Johnson会比赛。因此,我正在寻找的输出将是这样的(第一列是标题。逗号表示新列。GroupName来自User_Selection_Name列。UserName来自sAMAccountName列。)

enter image description here

因为在“ mw_user_selections”中,所有大写的命名列都是条件,但其中一些可以为NULL。例如,我可以在“ mw_user_selections”中有另一个条目作为Rule3,在这里我选择将COUNTRY_CODE = US和RANK_CODE = 64放置为其他所有列为NULL。在这种情况下,我的查询应输出上述内容以及以下内容:

enter image description here

因此,我无法弄清楚如何在多个列上联接并获得所需的结果。谁能帮忙吗?感谢您提供的任何指导。谢谢。

SELECT
    US.user_selection_name AS 'GROUP_NAME'
    , <?? where to get the other column from> as UserName
FROM
    [dbo].[mw_user_selections] US
    Inner JOIN [dbo].[mw_users] U1 ON US.COUNTRY_CODE = U1.country_code
    Inner JOIN [dbo].[mw_users] U2 ON US.GEO_AREA = U2.geo_area
    Inner JOIN [dbo].[mw_users] U3 ON US.LOCATION_CODE = U3.location_code
    inner join [dbo].[mw_users] U4 ON US.RANK_CODE = u4.rank_code
    inner join [dbo].[mw_users] U5 ON US.LEGAL_ENTITY = u5.legal_entity
    inner join [dbo].[mw_users] U6 ON US.BU_CODE = u6.bu_code
    inner join [dbo].[mw_users] U7 ON US.SERVICE_LINE_CODE = u7.service_line_code
    inner join [dbo].[mw_users] U8 ON US.SUB_SERVICE_LINE_CODE = u8.sub_service_line_code

这是我开始使用的代码,但这并没有为我带来想要的结果。

2 个答案:

答案 0 :(得分:2)

只需1个JOIN即可完成。
但是因为必须考虑所有这些可为空的设置值,所以该JOIN的ON子句将变大。

例如:

SELECT 
 s.user_selection_name AS GroupName, 
 u.sAMAccountName AS UserName
FROM [dbo].[mw_users] AS u  
JOIN [dbo].[mw_user_selections] AS s 
  ON (s.COUNTRY_CODE IS NULL OR s.COUNTRY_CODE = u.country_code) 
 AND (s.GEO_AREA IS NULL OR s.GEO_AREA = u.geo_area) 
 AND (s.LOCATION_CODE IS NULL OR s.LOCATION_CODE = u.location_code) 
 AND (s.RANK_CODE IS NULL OR s.RANK_CODE = u.rank_code) 
 AND (s.LEGAL_ENTITY IS NULL OR s.LEGAL_ENTITY = u.legal_entity) 
 AND (s.BU_CODE IS NULL OR s.BU_CODE = u.bu_code) 
 AND (s.SERVICE_LINE_CODE IS NULL OR s.SERVICE_LINE_CODE = u.service_line_code) 
 AND (s.SUB_SERVICE_LINE_CODE IS NULL OR s.SUB_SERVICE_LINE_CODE = u.sub_service_line_code)
ORDER BY s.user_selection_name, u.sAMAccountName;

这是一个包含表变量的代码片段以对其进行测试。

declare @mw_users table (userid int identity(1,1) primary key, sAMAccountName varchar(12), country_code char(2), geo_area varchar(10), 
location_code varchar(5), rank_code varchar(4), legal_entity int, bu_code varchar(4), service_line_code varchar(4), sub_service_line_code varchar(4),
first_name varchar(30), last_name varchar(30));
insert into @mw_users (sAMAccountName, country_code, geo_area, location_code, rank_code, legal_entity, bu_code, service_line_code, sub_service_line_code, first_name, last_name) values
 ('EMP012010275','GB','EMEIA',   'GB001',63,null,null,null,'0201','Mark','Power')
,('EMP012011143','GB','EMEIA',   'GB002',65,null,null,null,'0101','Lucas','Wonderson')
,('EMP011904661','US','Americas','US001',64,null,null,null,'0101','John','Doe')
,('EMP013562598','US','Americas','US002',63,null,null,null,'0101','Jane','Sue')
;
declare @mw_user_selections table (user_selection_id int identity(1,1) primary key, user_selection_name varchar(10), COUNTRY_CODE char(2), GEO_AREA varchar(10), 
LOCATION_CODE varchar(5), RANK_CODE int, LEGAL_ENTITY int, BU_CODE varchar(4), SERVICE_LINE_CODE varchar(4), SUB_SERVICE_LINE_CODE varchar(4));
insert into @mw_user_selections (user_selection_name, COUNTRY_CODE, GEO_AREA, 
LOCATION_CODE, RANK_CODE, LEGAL_ENTITY, BU_CODE, SERVICE_LINE_CODE, SUB_SERVICE_LINE_CODE) values
 ('Rule1', null, null, null,   63, null, null, null, '0201')
,('Rule2', 'US', null, null, null, null, null, null, '0101')
,('Rule3', 'US', null, null,   64, null, null, null, null)
;
SELECT 
 s.user_selection_name AS GroupName, 
 u.sAMAccountName AS UserName,
 concat(u.first_name,' ',u.last_name) AS UserFullName
FROM @mw_users AS u  
JOIN @mw_user_selections AS s 
  ON (s.COUNTRY_CODE IS NULL OR s.COUNTRY_CODE = u.country_code) 
 AND (s.GEO_AREA IS NULL OR s.GEO_AREA = u.geo_area) 
 AND (s.LOCATION_CODE IS NULL OR s.LOCATION_CODE = u.location_code) 
 AND (s.RANK_CODE IS NULL OR s.RANK_CODE = u.rank_code) 
 AND (s.LEGAL_ENTITY IS NULL OR s.LEGAL_ENTITY = u.legal_entity) 
 AND (s.BU_CODE IS NULL OR s.BU_CODE = u.bu_code) 
 AND (s.SERVICE_LINE_CODE IS NULL OR s.SERVICE_LINE_CODE = u.service_line_code) 
 AND (s.SUB_SERVICE_LINE_CODE IS NULL OR s.SUB_SERVICE_LINE_CODE = u.sub_service_line_code)
ORDER BY s.user_selection_name, u.sAMAccountName;

答案 1 :(得分:0)

您的查询应该是

SELECT users  
FROM mw_users AS u  
LEFT JOIN mw_selections AS s  
  --ON clause would contain a pair for every condition:  
    ON (u.COUNTRY = s.COUNTRY OR u.COUNTRY IS NULL)  
    AND (u.AREA = s.AREA OR u.AREA IS NULL)...  

组名将从mw_selections表中找到。