SQL选择列中的不同值/列

时间:2017-05-04 20:04:53

标签: sql sql-server sql-server-2008 tsql

我正在尝试在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

所以基本上对于每个用户我需要删除任何重复的角色,组和配置文件,无论它们在列中出现的顺序如何(即使重复项不是" t"堆叠"就像它们一样在角色和组列中。)

我非常确定答案是“没有”,但在这里:

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

2 个答案:

答案 0 :(得分:2)

这里我们通过XML和STUFF()连接字符串,最后注入 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

答案 1 :(得分:1)

它主要在UI / Presentation层中,但你可以通过使用row_number实现这一点,如果是1,你可以选择其他你可以选择NULL,如下所示:

#include <boost/regex.hpp>
#include <iostream>
#include <string>

int main()
{
    std::string line;
    boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );

    while (std::cin)
    {
        std::getline(std::cin, line);
        boost::smatch matches;
        if (boost::regex_match(line, matches, pat))
            std::cout << matches[2] << std::endl;
    }
}