Sql server 给定两个表,如何将它们合并到视图中?
给定以下ADuser表: 和组访问表: 我如何将它们整合到视图中,以便最终得到类似这样的结果,其中组织代码组合在一个匹配的userid下Sql server 给定两个表,如何将它们合并到视图中?,sql-server,sql-server-2017,Sql Server,Sql Server 2017,给定以下ADuser表: 和组访问表: 我如何将它们整合到视图中,以便最终得到类似这样的结果,其中组织代码组合在一个匹配的userid下 UserID Org Codes User1 M500_ABC|1098|123_KL|Z45557|f908L_P|234G|12345| User2 123_KL|Z45557|f908L_P| User3 12345| 请注意,由于User1属于多个组,即Group1和Group3,因此在最终视图中,这两个
UserID Org Codes
User1 M500_ABC|1098|123_KL|Z45557|f908L_P|234G|12345|
User2 123_KL|Z45557|f908L_P|
User3 12345|
请注意,由于User1属于多个组,即Group1和Group3,因此在最终视图中,这两个组中User1的所有组织代码都合并为1,并附加了额外的12345 |组织代码
到目前为止,我尝试的是:
CREATE VIEW UserOrgCodesView
AS SELECT ADuser.UserID, Group_Access.[Org Codes]
FROM ADuser
INNER JOIN Group_Access ON ADuser.[AD Group]=Group_Access.[AD Group];
但这已经在以下方面取得了进展
UserID Org Codes
User1 M500_ABC|1098|123_KL|Z45557|f908L_P|234G|12345|
User2 123_KL|Z45557|f908L_P|
User1 12345|
User3 12345|
组织代码组合在1个匹配用户标识下的位置
UserID Org Codes
User1 M500_ABC|1098|123_KL|Z45557|f908L_P|234G|12345|
User2 123_KL|Z45557|f908L_P|
User3 12345|
此查询还对输入[Org Codes]值使用TRIM,以帮助防止在将现有字符串连接在一起时在输出中出现“| |”
SELECT
u.UserId,
STRING_AGG( TRIM( '|' FROM g.[Org Codes] ), '|' ) AS [Org Codes]
FROM
ADuser AS u
INNER JOIN Group_Access AS g ON u.[AD Group] = g.[AD Group]
GROUP BY
u.UserId;
也就是说,像这样对数据进行非规范化通常是个坏主意。您应该将面向行的数据返回给客户端,并且只对UI层中的数据进行非规范化。如果SQL Server 2017以后,您可以使用STRING_AGG;如果SQL Server 2017之前,您可以使用XML PATH
创建表aduser ADGroup SYSNAME、UserID SYSNAME
创建表组\访问ADgroup sysname,OrgCodes VARCHAR4000
插入到aduser值中
'Group1'、'User1',
'Group2'、'User1';
插入组访问值
‘第一组’、‘M500_ABC | 1098 | 123 | KL | Z45557 | f908L | U P | 234G |’,
“第二组”,“123_KL | Z45557 | f908L|u P |”
创建视图用户OrgCodesView\u SQL2017及以后
像
选择ad.UserID、STRING_AGGgc.OrgCodes作为OrgCodes
来自aduser的广告
内部联接组\u作为gc访问
在gc.ADGroup=ad.ADGroup上
按ad.UserID分组
在2017年之前创建视图用户或代码视图
像
选择oad.UserID,然后从组中选择gc.OrgCodes+作为gc访问
内部连接aduser作为ad
在gc.ADGroup=ad.ADGroup上
其中ad.UserID=oad.UserID
对于XML路径,1,0作为组织代码
从aduser作为oad
按Oad.UserID分组
你可以尝试以下方法:
CREATE TABLE TmpTblADUser (GroupName VARCHAR(10), UserID VARCHAR(10));
INSERT INTO TmpTblGroupAccess VALUES
('Group1', 'M500_ABC|1098|123_KL|Z45557|f908L_P|234G|'),
('Group2', '123_KL|Z45557|f908L_P|'),
('Group3', '12345|')
CREATE TABLE TmpTblGroupAccess (GroupName VARCHAR(10), OrgCodes VARCHAR(1000));
INSERT INTO TmpTblGroupAccess VALUES
('Group1', 'M500_ABC|1098|123_KL|Z45557|f908L_P|234G|'),
('Group2', '123_KL|Z45557|f908L_P|'),
('Group3', '12345|')
CREATE VIEW UserOrgCodesView
AS SELECT u.UserID, g.OrgCodes
FROM TmpTblADUser u
INNER JOIN TmpTblGroupAccess g ON u.GroupName = g.GroupName;
SELECT t.UserID,
STUFF((SELECT OrgCodes + '' FROM UserOrgCodesView WHERE UserID = t.UserID FOR XML PATH ('')), 1, 0, '') AS GrupList
FROM UserOrgCodesView t
GROUP BY t.UserID
@DaleK Ive更新了帖子加入不起作用,因为广告组列有不同的格式-Group1和AD_Group1不经处理就无法加入。@AlwaysLearning噢,天哪,你说得对。我犯了个大错误,哈哈。现在我得到了一些东西,但是,我不知道如何将同一个用户合并到一个组织代码行中。请检查更新后的帖子在我为视图添加AS时出错:创建视图[dbo]。[UserOrgCodesView]AS选择u.Us。。。。。它说CREATEVIEW必须是批处理中唯一的语句…我怀疑它是因为我有“Go”。我删除了它,仍然抱怨关于数据非规范化的问题,你是对的,我们确实讨论过,但不幸的是,这是我们实现这一点的唯一方法。我们想到了许多解决方案,但它们都有局限性,这是执行和实施明智的唯一方法。例如,我们尝试使用具有多个访问列的表,但这限制了我们正在构建的安全性的层次结构。我们还尝试在excel中使用DAX公式,但它将组织代码的搜索限制为1个用户。顺便说一句,如果我没有尾随分隔符,例如结尾处的123|KL | Z45557 | f908L| P通知否,该怎么办。这会影响解决方案吗?@Cataster,对于SQL 2017以后的版本,这不是问题。对于早期版本,我已经更新了我的答案。如果我有和没有尾随的|分隔符,这两种情况都适用吗?很好。如果你不介意的话,还有一个问题。如果我们需要创建另一个视图,该视图具有相同的结果,但也包括整合的ADGroup,该怎么办?例如,User1属于组1和组3,对吗?然后会有3列,ADGroup,UserID,组织代码值第一行:Group1 | Group3 User1 M500 | u ABC | 1098 | 123 | u KL | Z45557 | f908L | P | 234G | 12345 |@Cataster,是的。您可以使用相同的逻辑连接组,因为我们已经连接了OrgCodes。这也是一个很好的答案!我看到您只是加入到视图中,但是通过单独运行SELECT语句,整合是临时进行的。如何将末尾的SELECT语句与CREATE视图相结合?你能在不深入第一个解决方案的情况下发布第二次编辑吗?我在你的问题中使用了视图定义。我删除了不必要的左函数。
CREATE TABLE TmpTblADUser (GroupName VARCHAR(10), UserID VARCHAR(10));
INSERT INTO TmpTblGroupAccess VALUES
('Group1', 'M500_ABC|1098|123_KL|Z45557|f908L_P|234G|'),
('Group2', '123_KL|Z45557|f908L_P|'),
('Group3', '12345|')
CREATE TABLE TmpTblGroupAccess (GroupName VARCHAR(10), OrgCodes VARCHAR(1000));
INSERT INTO TmpTblGroupAccess VALUES
('Group1', 'M500_ABC|1098|123_KL|Z45557|f908L_P|234G|'),
('Group2', '123_KL|Z45557|f908L_P|'),
('Group3', '12345|')
CREATE VIEW UserOrgCodesView
AS SELECT u.UserID, g.OrgCodes
FROM TmpTblADUser u
INNER JOIN TmpTblGroupAccess g ON u.GroupName = g.GroupName;
SELECT t.UserID,
STUFF((SELECT OrgCodes + '' FROM UserOrgCodesView WHERE UserID = t.UserID FOR XML PATH ('')), 1, 0, '') AS GrupList
FROM UserOrgCodesView t
GROUP BY t.UserID