Php mysql使用字段名称连接到子数组

时间:2017-05-23 07:21:28

标签: php mysql join left-join concat

我尝试使用ONE查询将表连接到子列中,列名为=>列值..

短表(1)"用户"结构与数据:

user_id   email        ...
1         xxx@xx.xx    ...
2         yyy@yy.yy    ...

短表(2)" users_permissions"结构与数据:

user_id   plugin_enter  offers_view  ...
1         1             0             ... 
2         1             1             ... 

如果我使用经典方法 - 加入左侧

SELECT `uperms`.*, `u`.*
FROM (`users` as u)
LEFT JOIN `users_permissions` as uperms ON `u`.`user_id` = `uperms`.`user_id`

我得到经典输出

[0] = array(
  'user_id' => 1,
  'email' => xxx@xx.xx,
  'plugin_enter' => 1,
  'offers_view' => 0
),
[1] = array(
  'user_id' => 2,
  'email' => yyy@yy.yy,
  'plugin_enter' => 1,
  'offers_view' => 1,
  ...
),

我需要的只是输出到子阵列中:

[0] = array(
  'user_id' => 1,
  'email' => xxx@xx.xx,
  'permissions => array(
      'plugin_enter' => 1,
      'offers_view' => 0
  ),
),
...

这可能与一个查询有关吗?

表2(权限)包含大约60列。是否可以使用列值将CONCAT列的名称,如果只连接到Table1的一行?

2 个答案:

答案 0 :(得分:1)

MySQL没有数组或嵌套结构,因此无法在SQL中执行此操作。

更改您的查询,以便为users_permissions的所有字段提供一致的命名方式。然后,您可以使用PHP循环将其键与该模式匹配的所有数组元素收集到permissions数组中。

查询:

SELECT u.*, up.plugin_enter AS perm_plugin_enter, up.offers_view AS perm_offers_view, ...
FROM users AS u
JOIN users_permissions AS up ON u.user_id = up.user_id

PHP:

foreach ($all_results as &$row) {
    $permissions = array();
    foreach ($row as $key => $value) {
        if (strpos($key, 'perm_') === 0) {
            $permission[substr($key, 5)] = $value;
            unset($row[$key]);
        }
    }
    $row['permissions'] = $permissions;
}

您可以通过连接表中的所有列名和值来实现:

SELECT u.*, CONCAT_WS(',', CONCAT('plugin_enter:', plugin_enter), CONCAT('offers_view:', offers_view), ...) AS permissions
FROM users AS u
JOIN users_permissions AS up ON u.user_id = up.user_id

然后您的PHP代码可以使用explode()$row['permissions']拆分为name:value对数组,然后将它们转换为PHP数组中的key=>value

另一种解决方案是重新设计users_permissions表:

user_id permission_type value
1       plugin_enter    1
1       offers_view     0
...
2       plugin_enter    1
2       offers_view     1
...

然后你可以查询:

SELECT u.*, GROUP_CONCAT(permission_type, ':', value) AS permission
FROM users AS u
JOIN users_permissions AS up on u.user_id = up.user_id

答案 1 :(得分:0)

另一种可能的解决方法是在查询中添加前缀 灵感来自帖子:https://stackoverflow.com/a/9926134/2795923

SELECT `u`.*, ':prefix_start:', `uperms`.*, ':prefix_end:'
FROM (`users` as u)
LEFT JOIN `users_permissions` as uperms ON `u`.`user_id` = `uperms`.`user_id`

输出数组如下所示:

[0] => array(
   'user_id' => 1
   'email' => xxx@xx.xx,
   'prefix_start' => 
   'plugin_enter' => 1,
   'offers_view' => 0
   'prefix_end' => 
)
...

然后简单的PHP脚本将prefix_start和prefix_end之间的所有数组数据添加到自己的子数组中。