首页 > 解决方案 > 如何有条件地加入

问题描述

我有两张桌子。

看起来像这样的“mw_user”表(我只有 4 条记录,因为我正在测试。) 用户表图像

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

user_selection_criteria 表图像

现在我要完成的是将我的用户分组到特定的选择 mw_user_selections 组中。因此,如果您查看表格,我可以看到对于 Rule1,仅指定了 RANK_CODE 和 SUB_SERVICE_LINE_CODE,因此只有 Mark Strong 匹配。对于第二个 Rule2,我填充了 COUNTRY_CODE 和 SUB_SERVICE_LINE_CODE。所以只有马修·佩里和道恩·约翰逊会匹配。所以我正在寻找的输出将是这样的(第一列是标题。逗号表示新列。GroupName 来自 User_Selection_Name 列。UserName 来自 sAMAccountName 列。)

在此处输入图像描述

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

在此处输入图像描述

所以我无法弄清楚我将如何加入多个列并获得我想要的结果。有人可以帮忙吗?我感谢您提供的任何指导。谢谢你。

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

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

标签: sqlsql-servertsqlleft-joininner-join

解决方案


只需 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;

推荐阅读