合并SQL查询的结果,其中大多数值都相同

时间:2016-06-09 11:19:39

标签: sql-server tsql

对不太好的标题感到抱歉。

我很想将各组结果合并在一起,以便快速查看某些数据。

如果我有这个问题:

SELECT 
    tblPriv.ID, tblGroups.Name AS 'Group', tblPriv.User, tblPriv.Role 
FROM 
    tblPriv 
INNER JOIN 
    tblGroups on tblPriv.ID = tblGroups.ID

返回这些结果:

ID    GROUP    USER    ROLE
---------------------------------
1     Taxes    DAVE    Admin
1     Taxes    JOHN    Admin
1     Taxes    BOB     PowerUser
2     Catering RON     Admin
2     Catering JACK    PowerUser
2     Catering JIM     PowerUser

(其中ID是关系,一组,存储在另一个表中)

我理想的做法是为一组获得1条记录:

ID    GROUP        ADMINS          POWERUSERS
---------------------------------------------
1     Taxes        DAVE; JOHN;     BOB
2     Catering     RON;            JACK; JIM;

我事先知道这些角色 - 它们始终保持不变,并且不会添加新角色。

我该怎么做呢? (我还将包括来自其他关系表的数据)

4 个答案:

答案 0 :(得分:2)

SELECT 
DISTINCT tp.ID, 
tp.[GROUP], 
ISNULL(STUFF(Admins.Admins, 1, 1, ''), '') AS Admins,
ISNULL(STUFF(PowerUsers.PowerUsers, 1, 1, ''), '') AS PowerUsers 
FROM tlbPriv AS tp
OUTER APPLY
(
    SELECT ' ' + tmp.[USER] + ';' 
    FROM  tlbPriv AS tmp
    WHERE tmp.ID = tp.ID AND [tmp].[ROLE] = 'Admin' FOR XML PATH('')
)Admins(Admins)
OUTER APPLY
(
    SELECT ' ' + tmp.[USER] + ';' 
    FROM  tlbPriv AS tmp
    WHERE tmp.ID = tp.ID AND [tmp].[ROLE] = 'PowerUser' FOR XML PATH('')
)PowerUsers(PowerUsers)

答案 1 :(得分:1)

针对您的特定问题:

select g.id, g.name,
       stuff((select '; ' + p.user
              from tblPriv p
              where p.id = g.id and p.role = 'Admin'
              for xml path ('') type
             ).value('', 'varchar(max)'
                    ), 1, 2, ''
            ) as admins,
       stuff((select '; ' + p.user
              from tblPriv p
              where p.id = g.id and p.role = 'PowerUser'
              for xml path ('') type
             ).value('', 'varchar(max)'
                    ), 1, 2, ''
            ) as PowerUsers
from tblGroups g

答案 2 :(得分:1)

标记的tsql,我假设这是针对MS SQL服务器的:

DECLARE     @MinLength INT          = 5     --Minimum Substring Length
DECLARE     @MaxLength INT          = 50    --Maximum Substring Length
DECLARE     @Delimeter VARCHAR(5)   = ' '
DECLARE     @T TABLE
            (
                  ID INT IDENTITY
                , chvStrings VARCHAR(64)  
            )
INSERT INTO @T VALUES
            ('I like cats'),
            ('I like dogs'),
            ('cats are great'),
            ('look at that cat'),
            ('I love Mittens the cat'),
            ('I love Mittens the cat a lot'),
            ('I love Mittens the cat so much'),
            ('Dogs are okay, I guess...')

SELECT TOP 10000 
    SUBSTRING(T.chvStrings, N.Number,  M.Number) AS Word,
    COUNT(M.number) AS [Count]
    --SUBSTRING(T.chvStrings,M.Number+1,1)
FROM        
    @T as T
CROSS APPLY 
    (SELECT N.Number
     FROM [master]..spt_values as N
     WHERE N.type = 'P' 
       AND N.number BETWEEN 1 AND LEN(T.chvStrings)) N
CROSS APPLY 
    (SELECT N.Number
     FROM [master]..spt_values as N
     WHERE N.type = 'P' 
       AND N.number BETWEEN @MinLength AND @MaxLength) M
WHERE       
    N.number <= LEN(t.chvStrings) - M.number + 1
    AND SUBSTRING(T.chvStrings, N.Number, M.Number) NOT LIKE '% '
    AND SUBSTRING(T.chvStrings, N.Number, M.Number) NOT LIKE '%[_]%'
    AND (SUBSTRING(T.chvStrings, N.Number,1) = @Delimeter OR  N.number = 1) 
    AND SUBSTRING(T.chvStrings,M.Number+1,1) NOT LIKE '%[a-z0-9]%'
    AND SUBSTRING(T.chvStrings,N.Number-1,1) NOT LIKE '%[a-z0-9]%'
GROUP BY  
    SUBSTRING(T.chvStrings, N.Number, M.Number)                      
ORDER BY    
    COUNT(T.chvStrings) DESC,
    LEN(SUBSTRING(T.chvStrings, N.Number, M.Number)) DESC 

答案 3 :(得分:0)

在MYSQL中使用group concat

 SELECT 
   tblPriv.ID
   , tblGroups.Name AS 'Group'
   , group_concat(t1.User) AS ADMINS,  group_concat(t2.User)  AS POWERUSERS
FROM tblPriv 
INNER JOIN tblGroups as t1 on t1.ID = tblGroups.ID and t1.user='ADMIN'
INNER JOIN tblGroups as t2 on t2.ID = tblGroups.ID and t1.user='POWERUSER'
GROUP BY tblPriv.ID