SQL 选择列中的不同值/列中的动态值计数

标签 sql sql-server sql-server-2008 t-sql

我正在尝试在 SSMS 2008 中编写 SQL 脚本,并且一直在网上寻找答案,但我发现没有一个完整的解决方案。

我有多个表中有关分配给用户的角色、组和配置文件的信息以及用于获取该信息的脚本。我得到的结果是“正确的”,但没有以客户希望看到的方式显示。角色、组和配置文件彼此之间没有任何关系,并且可能会为一个用户分配不同数量的角色(即 2 个角色、1 个组和 4 个配置文件)。

这是我的 SQL 脚本:

select distinct
DWUser.uid as ID,
DWUser.name as Name, 
DWRoles.name as Roles, 
DWGroup.name as Groups, 
DWFCProfile.name as Profiles
from DWUser
/* Joins for getting role name */
inner join DWUserToRole on DWUser.uid = DWUserToRole.uid
inner join DWRoles on DWUserToRole.rid = dwRoles.rid
/* Joins for getting group name */
inner join DWUserToGroup on DWUser.uid = DWUserToGroup.uid
inner join DWGroup on DWUserToGroup.gid = DWGroup.gid
/* Joins for getting profile name */
inner join DWFCProfileToUser on DWUser.uid = DWFCProfileToUser.uid
inner join DWFCProfile on DWFCProfileToUser.fpid = DWFCProfile.fpid

返回结果:

ID  Name        Roles                       Groups      Profiles

1   admin       Organization Administrator  Public      Contracts
1   admin       Organization Administrator  Public      My Basket 1
1   admin       Organization Administrator  Public      My Basket 2
1   admin       Organization Administrator  Public      My Basket 3
1   admin       System Administrator        Public      Contracts
1   admin       System Administrator        Public      My Basket 1
1   admin       System Administrator        Public      My Basket 2
1   admin       System Administrator        Public      My Basket 3
4   docuware    Organization Administrator  Public      Contracts
4   docuware    Organization Administrator  Public      My Basket 1
4   docuware    Organization Administrator  Public      My Basket 2
4   docuware    Organization Administrator  Public      My Basket 3
4   docuware    Organization Administrator  votosign    Contracts
4   docuware    Organization Administrator  votosign    My Basket 1
4   docuware    Organization Administrator  votosign    My Basket 2
4   docuware    Organization Administrator  votosign    My Basket 3

客户希望看到结果的方式是:

ID  Name        Roles                       Groups      Profiles

1   admin       Organization Administrator  Public      Contracts
                System Administrator                    My Basket 1
                                                        My Basket 2
                                                        My Basket 3
4   docuware    Organization Administrator  Public      Contracts
                                            votosign    My Basket 1
                                                        My Basket 2
                                                        My Basket 3

因此,基本上对于每个用户,我都需要删除任何重复的角色、组和配置文件,无论它们在列中出现的顺序如何(即,即使重复项不像角色和组列中那样“堆叠”) .

我很确定答案是“不”,但事实是:

有没有办法使用 Microsoft SQL 输出所需的结果?

最佳答案

这里我们通过 XML 和 STUFF() 连接字符串,最后注入(inject) CRLF 作为分隔符

需要明确的是,在这种情况下,只会返回两行数据,但每行数据可以有多行。

示例

Declare @YourTable Table ([ID] varchar(50),[Name] varchar(50),[Roles] varchar(50),[Groups] varchar(50),[Profiles] varchar(50))
Insert Into @YourTable Values
 (1,'admin','Organization Administrator','Public','Contracts')
,(1,'admin','Organization Administrator','Public','My Basket 1')
,(1,'admin','Organization Administrator','Public','My Basket 2')
,(1,'admin','Organization Administrator','Public','My Basket 3')
,(1,'admin','System Administrator','Public','Contracts')
,(1,'admin','System Administrator','Public','My Basket 1')
,(1,'admin','System Administrator','Public','My Basket 2')
,(1,'admin','System Administrator','Public','My Basket 3')
,(4,'docuware','Organization Administrator','Public','Contracts')
,(4,'docuware','Organization Administrator','Public','My Basket 1')
,(4,'docuware','Organization Administrator','Public','My Basket 2')
,(4,'docuware','Organization Administrator','Public','My Basket 3')
,(4,'docuware','Organization Administrator','votosign','Contracts')
,(4,'docuware','Organization Administrator','votosign','My Basket 1')
,(4,'docuware','Organization Administrator','votosign','My Basket 2')
,(4,'docuware','Organization Administrator','votosign','My Basket 3')

Select ID 
      ,Name 
      ,Roles    = replace((Select Stuff((Select Distinct '|'+Roles    From @YourTable Where ID=A.ID For XML Path ('')),1,1,'') ),'|',char(13)+char(10))
      ,Groups   = replace((Select Stuff((Select Distinct '|'+Groups   From @YourTable Where ID=A.ID For XML Path ('')),1,1,'') ),'|',char(13)+char(10))
      ,Profiles = replace((Select Stuff((Select Distinct '|'+Profiles From @YourTable Where ID=A.ID For XML Path ('')),1,1,'') ),'|',char(13)+char(10))
 From (
        Select Distinct ID,Name From @YourTable
      ) A

返回

ID  Name     Roles                       Groups     Profiles
1   admin    Organization Administrator  Public     Contracts
             System Administrator                   My Basket 1
                                                    My Basket 2
                                                    My Basket 3
4   docuware Organization Administrator  Public     Contracts
                                         votosign   My Basket 1
                                                    My Basket 2
                                                    My Basket 3

关于SQL 选择列中的不同值/列中的动态值计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43791910/

相关文章:

mysql - 是否可以从 MySQL 和 MSSQL 同步两个链接服务器中的两个表?

sql - 如何使用 Prepare()?

mysql - SQL 土耳其语语言显示问题

sql - 如何进行大量插入

sql-server - SQL Server聚集索引: (Physical) Data Page Order

sql-server-2008 - 将表从一个数据库复制到另一个数据库

mysql - 在连接表之前使用聚合函数

SQL四舍五入没有小数点的整数

sql-server - SQL Server - 何时使用聚集索引与非聚集索引?

sql-server - 如何在 LINQ to SQL 中使用系统存储过程