我试图使用一个查询将表加入具有列名=>列值的子数组中。
带有数据的简短表(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列。 如果仅将Table1连接到表1,则可以用列值CONCAT列名吗?
我认为这是不可能的在PHP中只有一个查询
将table2更改为uid,name,value之类的值,以避免60个列,并且无法维护查询。
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
感谢您的意见,但权限表并非所有具有相同"结尾"的列
好的,我展示了另一种方式,它不依赖于特定命名方案下的列。 它在查询中分配别名。
未来60列? 太多的写作..
没有什么可以自动执行。 您可以编写一个简单的脚本来从DDL创建查询。
我不明白你的问题。 是关于我的答案还是关于您在其他问题中找到的答案?
抱歉,不是您的回答。.我发布了主要问题的新解决方案。
好的,我决定通过少量修改使用您的第一个解决方案。 我用短前缀" perm_"重命名了表2" user_permissions"中的所有列名称,然后使用PHP foreach。
另一种可能的解决方案是在查询中添加前缀。
受帖子启发: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之间的所有数组数据添加到自己的子数组中。