从另一个表添加基于关闭值的列

时间:2014-07-18 14:16:55

标签: sql sql-server tsql stored-procedures

我有查询提取用户信息。

SELECT UserID, CompanyID, FName, LName FROM tblUsers  Where OrgType = 'business'

我有另一个查询来提取用户信息。

SELECT u.UserID, u.AccessID, t.AccessName FROM tblUserAccess as u Inner Join tblAccessType as t on u.AccessID = t.AccessID

最后,还有第三个查询来提取访问类型。

SELECT AccessID, AccessName, OrgType FROM tblAccessType WHERE OrgType = 'business'

tblAccessType中可以有X个不同的访问类型。随着时间的推移,不同的访问类型会增长此外,用户可以拥有X个访问类型。

如何编写将以下列格式返回数据的查询?

UserID CompanyID FName LName SALES MARKET ADMIN FIN

100    200       Jane  Doe     *                 *

101    200       John  Doe                   *

120    205       Mary  Smith   *             *

121    205       Mark  Smith   *                  *  

他的样本数据如下。

tblUsers

UserID CompanyID   FName LName  OrgType

100     200        Jane  Doe    business

101     200        John  Doe    business

120     205        Mary  Smith  business 

121     205        Mark  Smith  business

122     259        Fred  Wilson charity

tblUserAccess

UserID AccessID 

100    1

100    4

101    3

120    1

120    3

121    1

121    4 


tblAccessType

AccessID AccessName OrgType

1        SALES      business

2        MARKET     business

3        ADMIN      business 

4        FIN        business 

5        NOTAX      charity

6        SECURITY   government

2 个答案:

答案 0 :(得分:0)

如果您的访问类型(大部分)保持静态,那么这是一种解决此问题的方法。它不涉及旋转,这总是一个加号。

DECLARE @tblUsers TABLE
(
    UserID INT,
    Name VARCHAR(50)
)

INSERT INTO @tblUsers SELECT 100, 'John Doe'
INSERT INTO @tblUsers SELECT 101, 'Jane Doe'

DECLARE @tblUserAccess TABLE
(
    UserID INT,
    AccessID INT
)

INSERT INTO @tblUserAccess SELECT 100, 1
INSERT INTO @tblUserAccess SELECT 100, 4
INSERT INTO @tblUserAccess SELECT 101, 3

DECLARE @tblAccessType TABLE
(
    AccessID INT,
    AccessName VARCHAR(50)
)

INSERT INTO @tblAccessType SELECT 1, 'SALES'
INSERT INTO @tblAccessType SELECT 2, 'MARKET'
INSERT INTO @tblAccessType SELECT 3, 'ADMIN'
INSERT INTO @tblAccessType SELECT 4, 'FIN'


SELECT u.UserID
    , u.Name
    , [SALES] = MAX(CASE WHEN at.AccessName = 'SALES' THEN '*' ELSE ' ' END) 
    , [MARKET] = MAX(CASE WHEN at.AccessName = 'MARKET' THEN '*' ELSE ' ' END) 
    , [ADMIN] = MAX(CASE WHEN at.AccessName = 'ADMIN' THEN '*' ELSE ' ' END) 
    , [FIN] = MAX(CASE WHEN at.AccessName = 'FIN' THEN '*' ELSE ' ' END) 
FROM @tblUsers u
JOIN @tblUserAccess ua
    ON u.UserID = ua.UserID
JOIN @tblAccessType at
    ON ua.AccessID = at.AccessID
GROUP BY u.UserID, u.Name

结果:

UserID  Name    SALES   MARKET  ADMIN   FIN
100 John Doe    *                       *
101 Jane Doe                    *    

答案 1 :(得分:0)

您需要的是PIVOT ...我选择了动态PIVOT,因此如果您添加新的AccessTypes,系统会自动添加这些内容。

如果您想省略NULL数据,请将''*'' AS AccessVal更改为1 AS AccessVal,然后将MAX([AccessVal])更改为COUNT([AccessVal]) - 这将给你1/0而不是* / NULL

IF OBJECT_ID('tempdb..#tblUsers') IS NOT NULL DROP TABLE #tblUsers
IF OBJECT_ID('tempdb..#tblUserAccess') IS NOT NULL DROP TABLE #tblUserAccess 
IF OBJECT_ID('tempdb..#tblAccessType') IS NOT NULL DROP TABLE #tblAccessType 
IF OBJECT_ID('tempdb..##tblAccessPivot') IS NOT NULL DROP TABLE ##tblAccessPivot 

CREATE TABLE #tblUsers (UserID INT, CompanyID INT, FName VARCHAR(255), LName VARCHAR(255), OrgType VARCHAR(255))
CREATE TABLE #tblUserAccess (UserID INT, AccessID INT)
CREATE TABLE #tblAccessType (AccessID INT, AccessName VARCHAR(255), OrgType VARCHAR(255))

INSERT INTO #tblUsers (UserID, CompanyID, FName, LName, OrgType) 
VALUES (100, 200, 'Jane', 'Doe', 'Business'), 
       (101, 200, 'John', 'Doe', 'Business'), 
       (120, 205, 'Mary', 'Smith', 'Business'),
       (121, 205, 'Mark', 'Smith', 'Business'),
       (122, 259, 'Fred', 'Wilson', 'Charity')

INSERT INTO #tblAccessType (AccessID, AccessName, OrgType)
VALUES (1, 'Sales', 'Business'), 
       (2, 'Market', 'Business'), 
       (3, 'Admin', 'Business'), 
       (4, 'Fin', 'Business'),
       (5, 'NoTax', 'Charity'),
       (6, 'Security', 'Government')

INSERT INTO #tblUserAccess (UserID, AccessID)
VALUES (100,1),(100,4), -- JANE
       (101,3), -- JOHN
       (120,1),(120,3), -- MARY
       (121,1),(121,4) -- MARK

DECLARE @cols AS NVARCHAR(MAX), 
        @sql  AS NVARCHAR(MAX)

SET @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT AccessName AS y FROM #tblAccessType) AS Y
ORDER BY y
FOR XML PATH('')),
1, 1, N'');        

SET @sql = 'SELECT UserID, CompanyID, Fname, LName, '+@cols+'
            INTO ##tblAccessPivot
            FROM (SELECT U.UserID, U.CompanyID, U.Fname, U.LName, AT.AccessName, ''*'' AS AccessVal
                  FROM #tblUsers U
                  LEFT OUTER JOIN #tblUserAccess UA ON U.UserID=UA.UserID
                  LEFT OUTER JOIN #tblAccessType AT ON UA.AccessID=AT.AccessID) SUB
            PIVOT (MAX([AccessVal]) FOR AccessName IN ('+@cols+')) AS P'
PRINT @SQL
EXEC (@SQL)

SELECT *
FROM ##tblAccessPivot