2013-06-24 172 views
2

我正在尝试“PHP登录&用户管理”插件,该插件允许用户配置文件中的自定义字段。
然而,由于某种原因,这是在一个单独的表上实现的,所以为了拉起“电话号码”例如,我必须从login_users获取我的user_id,进入login_profile_fields表,找到正确的行,拉id和标签,并找到login_profiles中的行,其中id=pfield_iduser_id = user_idPHP/MySQL:如何查询行数据信息作为列数据?

我试图写一个SQL查询,显示最终的以下信息:

名称|电子邮件|电话号码|邮政编码|部门|技能|经理电子邮件|公司代码|状态

其中login_profiles选定值为X (例如:“请列出谁拥有的状态代码为1的所有用户的上述信息”)

有我的方式做到这一点?

另外,有没有一种方法,我可以自动填充login_profiles表中的值,来自login_profiles的值,像这样?

login_profiles

p_id | pfield_id | user_id | profile_value | Phone Number | Zip Code | ... 
1 | 1   | 1  | 18005551212 | {Select profile_value from login_profiles where user_id=user_id and pfield_id=1} | {Select profile_value from login_profiles where user_id=user_id and pfield_id=2} | ... 

这里是我当前的表:

login_profile_fields

id | section | type  | label  | 
1 | User Info | text_input | Phone Number | 
2 | User Info | text_input | Zip Code  | 
3 | Work Info | text_input | Department | 
4 | Work Info | text_input | Skills  | 
5 | Work Info | text_input | Manager Email | 
6 | Work Info | text_input | Company Code | 
7 | Work Info | checkbox | Status  | 

login_profiles

p_id | pfield_id | user_id | profile_value | 
1 | 1   | 1 | 18005551212 | 
2 | 2   | 1 | 90210 | 
3 | 3   | 1 | Marketing | 
4 | 4   | 1 | Segmentations and surveys | 
5 | 5   | 1 | [email protected] | 
6 | 6   | 1 | COMP1 | 
7 | 7   | 1 | 1 | 
1 | 1   | 2 | 18007771234 | 
2 | 2   | 2 | 90218 | 
3 | 3   | 2 | CEO | 
4 | 4   | 2 | Business strategy | 
5 | 5   | 2 | [email protected] | 
6 | 6   | 2 | COMP1 | 
7 | 7   | 2 | 1 | 

login_users

user_id| name   | email | 
    1 | Michael Bluth | [email protected] | 
    2 | George Bluth | [email protected] | 

我不是一个MYSQL的人通过培训,但我正在学习所有我可以,所以任何意见非常感谢!

+1

你不想这样做。做一个正常的查询,然后在代码中进行列转换。在获取数据时,客户端只需要一行代码就可以这样做了。在查询中动态地执行一些隐含的sql。 –

+0

@MarcB - 我非常不同意 - 数据透视表是一个非常普遍的需求,并且不需要大量的SQL,正如下面的bluefeet的答案所证明的那样。 –

+0

是的,如果mysql支持透视查询,那很好。但它不,所以你去了。 –

回答

2

要加入到想加入的外键关系的表,然后你可以使用聚合函数CASE表达式对行转换为列:

select u.name, 
    u.email, 
    max(case when f.label = 'Phone Number' then p.profile_value end) PhoneNumber, 
    max(case when f.label = 'Zip Code' then p.profile_value end) ZipCode, 
    max(case when f.label = 'Department' then p.profile_value end) Department, 
    max(case when f.label = 'Skills' then p.profile_value end) Skills, 
    max(case when f.label = 'Manager Email' then p.profile_value end) ManagerEmail, 
    max(case when f.label = 'Company Code' then p.profile_value end) CompanyCode, 
    max(case when f.label = 'Company Code' then p.profile_value end) Status 
from login_profile_fields f 
left join login_profile p 
    on f.id = p.pfield_id 
left join login_users u 
    on p.user_id = u.user_id 
group by u.name, u.email; 

SQL Fiddle with Demo

如果数值未知,则可能需要使用准备好的语句生成要执行的动态SQL:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(CASE WHEN f.label = ''', 
     label, 
     ''' THEN p.profile_value END) AS `', 
     label, '`' 
    ) 
) INTO @sql 
FROM login_profile_fields; 

SET @sql 
    = CONCAT('SELECT u.name, 
       u.email, ', @sql, ' 
      from login_profile_fields f 
      left join login_profile p 
       on f.id = p.pfield_id 
      left join login_users u 
       on p.user_id = u.user_id 
      group by u.name, u.email'); 

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

SQL Fiddle with Demo