Использование DISTINCT в SQL-запросах для исключения повторяющихся данных применительно к фреймворку CodeIgniter.

Использование DISTINCT в SQL-запросах для исключения повторяющихся данных применительно к фреймворку CodeIgniter. Как использовать DISTINCT в запросах MySQL, чтобы выбирать неповторяющиеся данные.

Чтобы не выдумывать пример, приведу реальный случай. Библиотека Ion Auth для аутентификации пользователей для CodeIgniter. Автор этой библиотеки, Ben Edmunds, использует таблицу users (данные пользователя) и users_groups (соответствие пользователей группе или группам). Ещё есть таблица groups для самих групп.  У себя, на loco.ru, в проектах с личным кабинетом мы используем Ion Auth. Я долго не мог понять почему в новой версии Ion Auth  2.x в случае, когда один пользователь относится к нескольким группам, то есть имеется несколько записей в таблице users_groups для одного пользователя, то при выводе списка пользователей нескольких групп этот пользователь выводится несколько раз (столько сколько он упоминается в users_groups).

Использовался такой код в контроллере (подчёркиваю функцию, которая виновата была в ошибке):

$groups = array(1,2,3,4);
$this->data['list_staff'] = $this->ion_auth->users($groups)->result(); // выбираем всех admins,teachers,students,users из зарегистрированных пользователей
foreach ($this->data['list_staff'] as $k => $one_staff)
{
$this->data['list_staff'][$k]->groups = $this->ion_auth->get_users_groups($one_staff->id)->result();
}

 

Потом в виде выводил

<?php foreach($list_staff as $one):?>
...<b><?php echo $one->first_name;?>&nbsp;<?php echo $one->last_name;?></b><br />
                        <span class="small1"><i>
                          <?php foreach ($one->groups as $group):?>
<?php echo $group->description;?>,
               <?php endforeach?>
 ...
          </div>
          <div class="clear">&nbsp;</div>
    </div>
<?endforeach;?>   

После этого и наблюдаю список с повторами одних и тех же пользователей.

Ben Edmunds добавил одну строку в библиотеку и всё встало на свои места и наступило маленькое счастье)). Спасибо Ben!

public function users($groups = NULL)
{
$this->trigger_events('users');

//default selects
        $this->db->select(array(
         $this->tables['users'].'.*', 
         $this->tables['users'].'.id as id', 
         $this->tables['users'].'.id as user_id'
        ));
...
         //join and then run a where_in against the group ids
         if (isset($groups) && !empty($groups))
         {
         $this->db->distinct();
$this->db->join(
        $this->tables['users_groups'], 
        $this->tables['users_groups'].'.user_id = ' . $this->tables['users'].'.id', 
        'inner'
        );

       ...
Вот примерно какой запрос формируется в этой функции: 
SELECT DISTINCT `users`.id, CONCAT(`users`.first_name, ' ', `users`.last_name) FROM (`users`) INNER JOIN `users_groups` ON `users_groups`.`user_id` = `users`.`id` WHERE `users_groups`.`group_id` IN (1, 2, 3, 4)"

Слово DISTINCT убирает повторы в выборке из users_groups!

SELECT DISTINCT - совсем не "основной инстинкт".

Источник: loco.ru

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (0)     Подпишитесь на RSS комментариев к этой статье.