2010-03-09 83 views
3

希望有人可以提供幫助。我有兩個表:多次選擇相同的列

Users 
    -UserID 
    -UserName 

UsersType 
    -UserTypeID 
    -UserID 

爲UsersTypeID可能的值是1〜6在該場景中,用戶可以具有多種類型,我需要檢索不同行,並與以下描述的列的每個用戶。

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

在這種情況下,喬有兩個不同的用戶類型(2,3)

這可能是易如反掌,但我一直在努力解決這個這麼久,我無言以對。有人可以幫忙嗎?

+3

什麼數據庫系統? – 2010-03-09 15:20:52

+0

哈哈,已經有6個答案。太多的廚師...... – Codesleuth 2010-03-09 15:25:31

+0

你可能想重新考慮你的查詢這些價值觀的策略。由於您不知道用戶可能具有多少種類型,因此將它們拉到單行中會有問題。簡單地查詢類型並將它們加載到應用程序中可能會更好。這就是說,托馬斯的答案看起來像是一個勝利者。 – 2010-03-09 15:26:42

回答

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 

(更新至最大,而不是最小值)

+0

我剛剛測試過這個。不起作用。最好你得到一個有4個零,或3個零和1(即只顯示一個類型成員資格)的用戶。 – Codesleuth 2010-03-09 15:33:17

+0

將其更改爲Max() – 2010-03-09 15:52:45

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 

如果你想添加UserType並且仍然有這項工作,你通常會想出一個替代策略。在這種情況下,您需要一個udf或存儲過程來構建查詢並運行它。

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 
+0

非常感謝大家,托馬斯給我帶來了我一直在尋找的解決方案...... Kudos – Mario 2010-03-09 15:53:47

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 

,你會通過在具有循環你的客戶端,但是對你的數據庫服務器和你的理智是一個很好的保證!

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] 
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 
+1

子查詢變得很慢,因爲您將對每一行執行一次表掃描。 – 2010-03-09 15:28:19

+0

只有6個。 – Codesleuth 2010-03-09 15:29:10

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