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     Bob@example.com     Billy    Bob
 2     Betty@example.com   Betty    Sue
 3     Beam@example.com    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,"Bob@example.com","Billy","Bob","Full Name","Billy John Bob"
 1,"Bob@example.com","Billy","Bob","Day Phone","123-234-3456"
 1,"Bob@example.com","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  | Bob@example.com   | Billy | Bob   | Billy John Bob | 123-234-3456 | 234-345-4567 |
 2  | Betty@example.com | Betty | Sue   |                |              |              | 24 Best St.

再次提前感谢,我希望这可以不用大惊小怪地完成。:\

4

1 回答 1

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

现在,如果您想动态执行此操作,这意味着您事先不知道要转置的列,那么您应该查看以下文章:

动态数据透视表(将行转换为列)

您的代码如下所示:

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

于 2012-10-10T01:54:38.930 回答