Laravel分页混乱了查询结果

I have a question about an strange behavior of a Laravel's 5.2 paginator: using the query builder I made a database query and tried to paginate the result.

If I look at the query results, I see this (I left only ids of records): query builder result.

Okay, let's try to paginate it: pagination result.

We can see the order is messed up and there are some duplicated items. If I try to use simplePaginate(12) method instead of paginate(12), the result is as expected.

What do you think about this behavior? How to solve this problem? Thanks.

UPD: added code example:

public static function getForCategoryPage($cityAlias, $categoryAlias, ParameterBag $params = null)
    {
        $appendsParams = [];
        $builder = DB::table('partners')
            ->join('cities', 'cities.id', '=', 'partners.city_id')
            ->join('categories', 'categories.id', '=', 'partners.category_id')
            ->join('comments', 'comments.partner_id', '=', 'partners.id', 'full outer')
            ->select([
                'partners.id', 'partners.name', 'categories.alias as category', 'categories.name as categoryname',
                'partners.alias', 'partners.body', 'partners.logo', DB::raw('AVG(comments.value) as rating'),
                'partners.updated_at as update_date'
            ])
            ->where([
                ['cities.alias', $cityAlias],
                ['categories.alias', $categoryAlias],
                ['partners.published', true]
            ])
            ->groupBy([
                'partners.id', 'cities.alias', 'categories.alias', 'categories.name'
            ])
            ->orderBy('pro', 'desc');
        /* Фильтры: */
        //Если есть параметр 'Наличие фотографий', подсоеденить таблицу изображений
        if ($params->has('photos') and $params->get('photos') === 'on') {
            $builder->join('images', 'partners.id', '=', 'images.gallery_id', 'inner');
            $builder->orderBy('pro', 'desc');
            $appendsParams['photos'] = 'on';
        }
        //Если есть параметр 'Наличие скидок', подсоеденить таблицу с акциями
        if ($params->has('discounts') and $params->get('discounts') === 'on') {
            $builder->join('promo', 'promo.partner_id', '=', 'partners.id', 'inner');
            $builder->orderBy('pro', 'desc');
            $appendsParams['discounts'] = 'on';
        }

        /* Сортировки: */
        if ($params->has('orderby')) {
            switch ($params->get('orderby')) {
                //По рейтингу
                case 'rating':
                    $builder->orderByRaw(DB::raw('rating desc nulls last'));
                    $appendsParams['orderby'] = 'rating';
                    break;
                //По дате добавления
                case 'date':
                    $builder->orderByRaw(DB::raw('update_date desc nulls last'));
                    $appendsParams['orderby'] = 'date';
                    break;
            }
        }

        dd($builder->paginate(12)->appends($appendsParams)->keyBy('id'));
        //return $builder->paginate(12)->appends($appendsParams);
    }