2013-07-14 8 views
9

나는 내 직원과 그룹 테이블간에 많은 관계를 가지고 있습니다. 피벗 테이블을 만들었고 모든 것이 올바르게 작동합니다. 그러나, 나는 그들이 표시 순서를 결정하는 데 사용하는 직원 테이블에 sortOrder 열이 있습니다. sortOrder 열의 값이 1 인 직원이 먼저 와야하며 2의 값이 초이어야합니다. (또는 내림차순으로 정렬 된 경우 뒤로) sortOrder 열은 null 값을 허용하는 정수 열입니다.Laravel에서 Eloquent를 사용하여 NULL 값을 마지막으로 정렬하는 방법

정렬 열을 기준으로 직원을 정렬하도록 그룹 모델을 설정했지만 문제가 발생했습니다. Null 값은 항상 먼저 표시됩니다. 내가 사용하는 일반적인 "오름차순"또는 "desc"대신 ISNULL 및 유사한 SQL 메서드를 사용하여 시도했지만 오류가 발생합니다.

여기 내 그룹 모델에서 코드입니다 :

class Group extends Eloquent { 

public function employees() 
    { 
     return $this->belongsToMany("Employee")->orderBy('sortOrder', 'asc'); 
    } 
} 

그리고 여기 내 모델에 액세스하기 위해 컨트롤러에서 사용하는 내용은 다음과 같습니다

$board = Group::find(6)->employees; 

NULL 값이 마지막으로 정렬에 Laravel의 트릭은 무엇을?

답변

5
public function employees() 
{ 
    return $this 
     ->hasMany('Employee') 
     ->select(['*', DB::raw('IF(`sortOrder` IS NOT NULL, `sortOrder`, 1000000) `sortOrder`')]) 
     ->orderBy('sortOrder', 'asc'); 
} 

설명 :
IF 문이 여기에 문제를 해결합니다. NULL 값을 찾으면 큰 숫자가 sortOrder에 대신 할당됩니다. NULL 값이 아니라면 실제 값이 사용됩니다. 대신 당신은 또한 할 수있는 임의의 많은 수에 의존

+0

감사! 이것은 완벽하게 작동합니다! Fluent chain 방법이 Eloquent에서 사용될 수 있다는 것을 몰랐습니다. – eagle0042

+0

선택에 괄호의 중요성을 말씀해 주시겠습니까? 나는 그들과 이상한 문제를 겪고있다. 두 개의 개발 컴퓨터가 있고 그 중 하나는 대괄호에 문제가 없으며 다른 하나는 FatalErrorException을 발생시킵니다. 나는 그것들을 꺼냈다. 이제 두 컴퓨터 모두에서 작동하고 나의 쿼리 결과는 변경되지 않은 것 같다. – eagle0042

+0

'select()'메소드에 전달 된 대괄호는 Array의 새로운 구문입니다. 이 기능은 새로운 기능이므로 PHP 5.4와 함께 제공됩니다. 컴퓨터 중 하나는 5.4를 실행하고 다른 하나는 실행하지 않습니다. http://php.net/manual/en/language.types.array.php 또는 http://php.net/manual/en/migration54.new-features.php – Andreyco

2

은 :

public function employees() 
{ 
    return $this 
     ->hasMany('Employee') 
     ->select(['*', DB::raw('sortOrder IS NULL AS sortOrderNull')]) 
     ->orderBy('sortOrderNull') 
     ->orderBy('sortOrder'); 
} 

그것은의 추가 혜택 SQLite는에 의해 지원되고있다.

-1
->orderBy('sortOrder', 'is', 'null')->orderBy('sortOrder', 'asc') 

+0

실제로, NULL 값을 마지막으로 추가하지 않는 'order by sortOrder DESC, sortOrder ASC'가 포함 된 쿼리가 생성됩니다. – junkystu

+0

@junkystu : 어떻게 확인 했습니까? 아직 SQL 로깅 작업을 수행하지 못했습니다. Eloquent 5.0 btw를 사용하고 있습니다. –

+1

[디버그 바] (https://github.com/barryvdh/laravel-debugbar)를 사용하면 매우 유용하며 심지어 다른 유용한 것들 중에서 ajax를 통해 실행되는 쿼리를 볼 수도 있습니다 – junkystu

13

Laravel은 ISNULL 메서드를 고려하지 않지만 원시 쿼리로 전달할 수 있으며 if 문보다 효율적이므로 결과를 1000000 이상으로 유지하면 그대로 사용할 수 있습니다. 직원 수 :

public function employees() 
{ 
    return $this->hasMany('Employee') 
       ->orderBy(DB::raw('ISNULL(sortOrder), sortOrder'), 'ASC'); 
} 
+0

이것은 숫자가 아닌 경우에도 작동하는 해결책입니다 값 (예 : 날짜). –

21

필드에 마이너스 기호를 추가하고 주문을 DESC로 변경하기 만하면됩니다.

$q->orderBy(\DB::raw('-`sortOrder`'), 'desc'); 
+6

laravel 5.1의 경우 : $ q-> orderBy (\ DB :: raw ('- sortOrder'), 'desc'); – Blum

+3

Laravel 5.4 : $ q-> orderByRaw ("- start_date", 'DESC') –

0

숫자 타입 용의 PostgreSQL

대한 해결 : 텍스트 유형의

DB::table('t') 
    ->select(['id', 'val']) 
    ->orderBy(DB::raw("coalesce(val, 0)"), 'desc') 

:

orderBy(DB::raw("coalesce(val, '')"), 'desc') 

트릭은 제로로 정렬 열에 NULL 값을 대체하는 (또는 빈 문자열)을 사용하여 일반 정수 (또는 텍스트) 값으로 정렬 할 수 있습니다.

1

Laravel 5.2 이상에서는 orderByRaw으로 전화하십시오. 심지어 열이 아닌 집계 된 값을 통해 정렬 할 수도 있습니다. 다음 예에서 max_st은 서브 모델이없는 경우 null이 될 수 있습니다.

Model::where('act', '2') 
    ->leftJoin('submodels', 'model.id', '=', 'submodels.model_id') 
    ->select('models.*', DB::raw('MAX(submodels.st) as max_st')), 
    ->orderByRaw('max_st DESC NULLS LAST'); 
관련 문제