2017-05-23 7 views
2

I 열 이름 => 열 값을 가진 서브 어레이로 하나 개의 질의를 사용하여 테이블에 참여하려고 .. 데이터빌 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 
), 
), 
... 

ONE 쿼리이게 가능을 할까?

표 2 (사용 권한)에는 약 60 개의 열이 있습니다. Table1에 한 행만 조인 된 경우 열 값으로 열의 이름을 CONCAT 할 수 있습니까?

+0

나는 이것이 단지 하나의 쿼리에 대해서만 가능하다고 생각한다. – Chinito

+0

당신의 table2를 uid, name, value와 같이 변경하여 60 개의 열을 피하고 쿼리를 유지할 수 없다. –

답변

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로 변환합니다.

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

이 그럼 당신은 조회 할 수 있습니다 :

또 다른 해결 방법은 users_permissions 테이블을 재 설계하는 것입니다

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

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 할 수 있습니다.