多次选择同一列

时间:2010-03-09 15:16:14

标签: sql select

希望有人可以提供帮助。我有两张桌子:

Users
  -UserID
  -UserName

UsersType
  -UserTypeID
  -UserID

UsersTypeID的可能值为1到6.在该场景中,用户可能有多种类型,我需要为每个用户检索具有下述列的不同行。

UserName - Type1 - Type2 - Type3 - Type4
Joe            0       1       1       0

在这种情况下,Joe有两种不同的用户类型(2,3)

这可能很容易,但我已经解决了这个问题很久以至于我一无所知。有人可以帮忙吗。

7 个答案:

答案 0 :(得分:4)

这是一个标准的交叉表输出,您应该可以谷歌。虽然在SQL中不推荐,但您可以执行以下操作:

Select Users.Username
    , Max( Case When UsersType.UserTypeId = 1 Then 1 Else 0 End ) As Type1
    , Max( Case When UsersType.UserTypeId = 2 Then 1 Else 0 End ) As Type2
    , Max( Case When UsersType.UserTypeId = 3 Then 1 Else 0 End ) As Type3
    , Max( Case When UsersType.UserTypeId = 4 Then 1 Else 0 End ) As Type4
From Users
        Join UsersType
            On UsersType.UserId = Users.UserId
Group By Users.UserName

(更新为Max而不是Min)

答案 1 :(得分:1)

SELECT U.[UserName]
    , AVG(CASE WHEN UT.[UserTypeID] IS 1 THEN 1 ELSE NULL END) AS N'Type 1'
    , AVG(CASE WHEN UT.[UserTypeID] IS 2 THEN 2 ELSE NULL END) AS N'Type 2'
    , AVG(CASE WHEN UT.[UserTypeID] IS 3 THEN 3 ELSE NULL END) AS N'Type 3'
    , AVG(CASE WHEN UT.[UserTypeID] IS 4 THEN 4 ELSE NULL END) AS N'Type 4'
    , AVG(CASE WHEN UT.[UserTypeID] IS 5 THEN 5 ELSE NULL END) AS N'Type 5'
    , AVG(CASE WHEN UT.[UserTypeID] IS 6 THEN 6 ELSE NULL END) AS N'Type 6'
FROM [Users] U
    INNER JOIN [UserType] UT ON UT.[UserID] = U.[UserID]
GROUP BY U.[UserName]
ORDER BY U.[UserName]

答案 2 :(得分:1)

使用数据透视,你可以

SELECT 
    UserName, 
    [1] as 'type1', 
    [2] as 'type2', 
    [3] as 'type3', 
    [4] as 'type4', 
    [5] as 'type5', 
    [6] as 'type6'
FROM (
        SELECT 
            UserName, 
            userTypeId 
        FROM 
            users LEFT OUTER JOIN UsersType
            ON users.userId = usersType.userid
    ) AS src
PIVOT (
    count(userTypeId) FOR userTypeId IN ([1],[2],[3],[4],[5],[6]) ) AS pvt

答案 3 :(得分:0)

已知的有限数量的UserTypeID值使这种(相对)直接的策略成为可能。这看起来很毛茸茸,但只要您的索引很好,性能就会很好。

Select U.UserName, Case When UT1.UserType Is Null Then 0 Else 1 End As Type1,   
    Case When UT2.UserType Is Null Then 0 Else 1 End As Type2,
    Case When UT3.UserType Is Null Then 0 Else 1 End As Type3, 
    Case When UT4.UserType Is Null Then 0 Else 1 End As Type4, 
    Case When UT5.UserType Is Null Then 0 Else 1 End As Type5, 
    Case When UT6.UserType Is Null Then 0 Else 1 End As Type6, 
From Users As U
    Left Join UsersType As UT1 On U.UserID = UT1.UserID
    Left Join UsersType As UT2 On U.UserID = UT2.UserID     
    Left Join UsersType As UT3 On U.UserID = UT3.UserID     
    Left Join UsersType As UT4 On U.UserID = UT4.UserID     
    Left Join UsersType As UT5 On U.UserID = UT5.UserID     
    Left Join UsersType As UT6 On U.UserID = UT6.UserID     
Where UT1.UserTypeID = 1 And UT2.UserTypeID = 2
    And UT3.UserTypeID = 3 And UT4.UserTypeID = 4
    And UT5.UserTypeID = 5 And UT6.UserTypeID = 6

如果您希望能够添加UserTypes并且仍然可以执行此操作,则通常会提出备用策略。在这种情况下,您需要一个udf或存储过程来构造查询并运行它。

答案 4 :(得分:0)

您想使用LEFT JOIN。试试这样的事情

SELECT
UserName
U1.UserTypeID AS Type1
U2.UserTypeID AS Type2
U3.UserTypeID AS Type3
U4.UserTypeID AS Type4
FROM Users U
LEFT JOIN UsersType U1 ON U.UserID  = U1.UserID AND UserTypeID  = 1
LEFT JOIN UsersType U2 ON U.UserID  = U2.UserID AND UserTypeID  = 2
LEFT JOIN UsersType U3 ON U.UserID  = U3.UserID AND UserTypeID  = 3
LEFT JOIN UsersType U4 ON U.UserID  = U4.UserID AND UserTypeID  = 4

如果您希望行只返回true或false,那么我会这样做(它是SQL Server特定的):

SELECT
UserName
CASE WHEN U1.UserTypeID IS NOT NULL THEN 1 ELSE 0 END AS Type1
CASE WHEN U2.UserTypeID IS NOT NULL THEN 1 ELSE 0 END AS Type2
CASE WHEN U3.UserTypeID IS NOT NULL THEN 1 ELSE 0 END AS Type3
CASE WHEN U4.UserTypeID IS NOT NULL THEN 1 ELSE 0 END AS Type4
FROM Users U
LEFT JOIN UsersType U1 ON U.UserID  = U1.UserID AND UserTypeID  = 1
LEFT JOIN UsersType U2 ON U.UserID  = U2.UserID AND UserTypeID  = 2
LEFT JOIN UsersType U3 ON U.UserID  = U3.UserID AND UserTypeID  = 3
LEFT JOIN UsersType U4 ON U.UserID  = U4.UserID AND UserTypeID  = 4

答案 5 :(得分:0)

要获得完全结果集,您正在寻找的查询是丑陋的并且不是很可扩展(例如,如果您有100个usertypes)但是在这里你去

  select 
     u.username,
     isnull(ut1.Usertypeid,0) as Type1,
     isnull(ut2.Usertypeid,0) as Type2,
     isnull(ut3.Usertypeid,0) as Type3,
     isnull(ut4.Usertypeid,0) as Type4,
     isnull(ut5.Usertypeid,0) as Type5,
     isnull(ut6.Usertypeid,0) as Type6

    from 
        users u
    left outer join 
        userstype ut1 on u.userid = ut1.userid and ut1.usertypeid = 1
    left outer join 
        userstype ut2 on u.userid = ut2.userid and ut2.usertypeid = 2
    left outer join 
        userstype ut3 on u.userid = ut3.userid and ut3.usertypeid = 3
    left outer join 
        userstype ut4 on u.userid = ut4.userid and ut4.usertypeid = 4
    left outer join 
        userstype ut5 on u.userid = ut5.userid and ut5.usertypeid = 5
    left outer join 
        userstype ut6 on u.userid = ut6.userid and ut6.usertypeid = 6

修改

一旦你达到你的第10个用户类型,希望常识会开始(希望在10号之前),你会想到自己这不能继续!

当发生这种情况时,你最好不要像这样查询

select 
     u.username,
     ut..Usertypeid
    from 
        users u
    left outer join 
        userstype ut
    on u.userid = ut.userid

然后,您将获得一个看起来像

的结果集
  Username | UserTypeID
  ---------------------
  Joe      | 3
  Joe      | 4

你必须在你的客户端循环,但对你的数据库服务器和你的理智是很好的!

答案 6 :(得分:0)

由于您说明该类型只有6个值,我可以建议使用子查询:

SELECT  UserName
        ,(
            SELECT  CONVERT(bit, COUNT(UserTypeID))
            FROM    UsersType AS ut
            WHERE   ut.UserID = u.UserID
                    AND ut.UserTypeID = 1
        ) AS Type1
        ,(
            SELECT  CONVERT(bit, COUNT(UserTypeID))
            FROM    UsersType AS ut
            WHERE   ut.UserID = u.UserID
                    AND ut.UserTypeID = 2
        ) AS Type2
        ,...
FROM    Users AS u