PHP / MySQL:如何查询行数据信息作为列数据?

时间:2013-06-24 15:46:56

标签: php mysql sql

我正在尝试“PHP登录和用户管理”插件,该插件允许用户个人资料中的自定义字段。
但是,出于某种原因,这是在单独的表上实现的,所以为了例如,拉出“电话号码”,我必须从login_users获取我的user_id,进入login_profile_fields表,找到正确的行,拉出id和标签,然后在login_profiles中找到id=pfield_id和{{1 }}

我正在尝试编写SQL查询以最终显示以下信息:

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

login_profiles中选择的值是X. (例如:“列出状态代码为1的所有用户的上述信息)

我有办法做到这一点吗?

或者,是否可以使用login_profiles 的值自动填充login_profiles表,如此?

login_profiles

user_id = user_id

以下是我目前的表格:

login_profile_fields

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_profiles

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_users

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 | theboss@company.com |
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 | theboard@company.com |
6    | 6         | 2 | COMP1 |
7    | 7         | 2 | 1 |

我不是训练有素的MYSQL人,但我正在尽我所能,所以非常感谢任何建议!

1 个答案:

答案 0 :(得分: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