2012-10-10 69 views
1

非常感謝您提供幫助的人。我知道我已經看到了這樣做過沒有太多的痛苦,但不能似乎找到解決方案多連接查詢,樞軸?麻煩

我的數據庫看起來類似:

`tbl_user: 
---------- 
id   (pkey) 
email 
fName 
lName 

tbl_userSparseType: 
------------------- 
id   (pkey) 
varName 
displayName 

tbl_userSparse: 
--------------- 
id   (pkey) 
value  (Value of Sparse Type) 
user_id (=> tbl_user.id) 
userSparseType_id  (=> tbl_userSparseType.id) 

樣本數據:

tbl_user: 
(id, email,    fName, lName) 
1  [email protected]  Billy Bob 
2  [email protected] Betty Sue 
3  [email protected] Jim  Beam 

tbl_userSparseType: 
(id, varName, displayName) 
1  fullName Full Name 
2  dayPhone Day Phone 
3  nightPhone Night Phone 
4  cellPhone Cell Phone 
5  homeAddr Home Address 

tbl_userSparse: 
(id, value,    user_id, userSparseType_id) 
1  Billy John Bob  1   1 
2  James B. Beam  3   1 
3  123-234-3456  1   2 
4  234-345-4567  1   4 
5  24 Best st.  2   5 
6  456-567-6789  3   3 

我試着做兩個左連接,但這給了我一個tbl_user行爲每個稀疏條目,如:

(id, email,   fName, lName, displayName, value) 
1,"[email protected]","Billy","Bob","Full Name","Billy John Bob" 
1,"[email protected]","Billy","Bob","Day Phone","123-234-3456" 
1,"[email protected]","Billy","Bob","Cell Phone","234-345-4567" 

儘管只有45分鐘左右的時間,但我無法找到更明顯的命名方式來獲取更多內容,我需要一種動態的方式來只提取所有適用於tbl_user行子集的顯示名稱查詢:

WHERE tbl_user.id IN (1,2) 

id | email    | fName | lName | Full Name,  | Day Phone | Cell Phone | 
Home Address 
------------------------------------------------------------------------------------------------------- 
1 | [email protected] | Billy | Bob | Billy John Bob | 123-234-3456 | 234-345-4567 | 
2 | [email protected] | Betty | Sue |    |    |    | 24 Best St. 

再次感謝,我希望這可以做到沒有太多的大驚小怪。 :\

+0

您可能必須將功能構建到應用程序中。你想做什麼有違SQL如何工作。 –

回答

2

不幸的是,MySQL沒有PIVOT函數,這基本上是你要做的。因此,您需要使用CASE語句的聚合函數。如果你知道的列數,那麼你可以硬編碼值:

select u.id, 
    u.email, 
    u.fname, 
    u.lname, 
    max(case when t.displayname = 'Full Name' then us.value end) FullName, 
    max(case when t.displayname = 'Day Phone' then us.value end) DayPhone, 
    max(case when t.displayname = 'Cell Phone' then us.value end) CellPhone, 
    max(case when t.displayname = 'Home Address' then us.value end) HOmeAddress 
from tbl_user u 
left join tbl_userSparse us 
    on u.id = us.user_id 
left join tbl_userSparseType t 
    on us.userSparseType_id = t.id 
where u.id in (1, 2) 
group by u.id, u.email, u.fname,u.lname; 

SQL Fiddle With Demo

現在,如果要動態執行此,這意味着你不知道時間提前列轉,那麼你應該閱讀以下文章:

Dynamic pivot tables (transform rows to columns)

您的代碼應該是這樣的:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when t.displayname = ''', 
     t.displayname, 
     ''' then us.value end) AS ', 
     replace(t.displayname, ' ', '') 
    ) 
) INTO @sql 
FROM tbl_userSparse us 
left join tbl_userSparseType t 
    on us.userSparseType_id = t.id; 

SET @sql = CONCAT('SELECT u.id, u.email, u.fname, u.lname, ', @sql, ' 
        from tbl_user u 
        left join tbl_userSparse us 
        on u.id = us.user_id 
        left join tbl_userSparseType t 
        on us.userSparseType_id = t.id 
        where u.id in (1, 2) 
        group by u.id, u.email, u.fname, u.lname'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

請參閱SQL Fiddle with Demo