2015-01-30 3 views
3

Я работаю над веб-приложением с mysql с участием таблицы роли пользователя, где хранятся уровни разрешений, а также идентификаторы роли и связанные с именами пользователей и их идентификаторы (избыточность для продолжения поддержки устаревшего кода).Как заставить mysql Group_Concat работать с дополнительной информацией CONCAT?

Я хочу показать роль каждого пользователя в виде разделенного запятой списка на простом английском языке с минимальным ударом по DB (> 1k пользователей), а также с их уровнем разрешений.

права сохраняются как биты в ismanager и ishead колонн и roleids сконструированы так, чтобы define_roles (ид, RoleName)

Вот что у меня работает (но не показывает уровни пользователей)

<? 
$rolenames = array(); 
foreach($db->query("SELECT id, rolename FROM define_roles") as $row) 
{ 
    $rolenames[$row['id']] = $row['rolename']; 
} 

foreach($db->query("SELECT DISTINCT userid, username, 
         GROUP_CONCAT(DISTINCT roleid ORDER BY roleid) AS idlist 
         FROM user_roles 
         GROUP BY userid 
         ORDER BY username ASC") as $row) 
{ 
    $rolestring = ''; 
    //echo $row['idlist']; 
    foreach(explode(',',$row['idlist']) as $id) 
    { 
     $rolestring .= " ".$rolenames[$id].","; 
    } 
    $rolestring = rtrim($rolestring,','); 

    echo "<tbody> 
      <tr> 
       <td><font size='1'>" . $row['username'] . "</font></td> 
       <td><font size='1'>" .$rolestring. "</font></td> 
      </tr>"; 
} 
?> 

Выход:

  • TestUser продажи
  • UserTest2 Продажа, экспедиционный, дворников

То, что я хочу видеть это

  • TestUser продаж (менеджер)
  • UserTest2 продаж, экспедиционного (руководитель), дворников (менеджер)

Лучшее, что я мог придумать (хотя он не работает) составляет:

$rolenames = array(); 
foreach($db->query("SELECT id, rolename FROM define_roles") as $row) 
{ 
    $rolenames[$row['id']] = $row['rolename']; 
    $rolenames[$row['id']."10"] = $row['rolename']." (Manager)"; 
    $rolenames[$row['id']."01"] = $row['rolename']." (Head)"; 
    $rolenames[$row['id']."11"] = $row['rolename']." (Head)"; 
} 

foreach($db->query("SELECT DISTINCT userid, username, 
         GROUP_CONCAT 
         (
          CONCAT(roleid,ismanager,ishead) ORDER BY roleid 
         ) AS idlist 
         FROM user_roles 
         GROUP BY userid 
         ORDER BY username ASC") as $row) 

ответ

2

Во-первых, вы, вероятно, должны нормализовать йо ur, чтобы у вас была отдельная таблица, связывающая пользователей и определенные роли. Но это отдельная вещь, и я ценю, что вы не сможете этого сделать.

Если я понял, что в таблицах правильно, то ответ на это, я думаю:

SELECT 
    userid, 
    username, 
    GROUP_CONCAT(DISTINCT 
     CONCAT(
      (SELECT d.rolename FROM define_roles AS d 
      WHERE d.id = roleid) 
     ), 
     IF(ismanager = 1, " (Manager)", ""), 
     IF(ishead = 1, " (Head)", "") 
    ) AS roles 
FROM user_roles 
GROUP BY userid; 

Вам не нужно будет первоначальный SQL, где вы смотрели вверх rolenames от define_roles.

[РЕДАКТИРОВАТЬ]: Извините, обновлены скобками вокруг внутреннего SELECT.

+0

Спасибо! Имейте небольшую икоту, но это отвечает на вопрос, удаляю ли SELECT внутри CONCAT так с места в карьер, поэтому я отметил как ответ. Я все еще получаю сообщение об ошибке (phpmyadmin точно не дает полезные отчеты об ошибках) «рядом с SELECT d.rolename FROM define_roles AS d WHERE d.id = roleid» Я проверил на случай, если ошибочно опечатаю колонку или имя таблицы, но, похоже, это не так. Я думал, что мне, возможно, придется определять таблицу user_roles как r и делать r.roleid, но это не делалось. – BZohar

+0

Скобки сделали трюк. Удивительно, спасибо! – BZohar

Смежные вопросы