2017-05-23 31 views
2

我嘗試加入使用一個查詢與列名=>列值的子陣列表..PHP的MySQL加入與字段名稱子陣列

短表(1)「用戶」結構數據:

user_id email  ... 
1   [email protected] ... 
2   [email protected] ... 

短表(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' => [email protected], 
    'plugin_enter' => 1, 
    'offers_view' => 0 
), 
[1] = array(
    'user_id' => 2, 
    'email' => [email protected], 
    'plugin_enter' => 1, 
    'offers_view' => 1, 
    ... 
), 

所有我需要的是輸出到子陣就象這樣:

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

這是可以做到使用一個查詢?

表2(權限)包含大約60列。如果加入Table1只有一行,是否可以用列值CONCAT列名?

+0

我認爲這是不可能在PHP只有一個查詢 – Chinito

+0

更改您的table2到像uid,名稱,價值,以避免60 colums和不可能維護查詢。 –

回答

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對數組,並且t母雞將它們轉換爲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 
+0

感謝您的意見,但權限表並不是所有的列都有相同的「結尾」 – drozdo

+0

好的,我展示了另一種方法,它不依賴於特定命名方案後面的列。它在查詢中分配別名。 – Barmar

+0

fuuh 60列?它寫得太多.. – drozdo

0

另一種可能sollution是添加前綴進行查詢。
郵寄啓發: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' => [email protected], 
    'prefix_start' => 
    'plugin_enter' => 1, 
    'offers_view' => 0 
    'prefix_end' => 
) 
... 

那麼容易的PHP腳本prefix_start之間添加所有陣列數據和prefix_end到自己的子陣。