복붙노트

[SQL] 어떻게 Laravel 쿼리 빌더를 사용하여 하위 쿼리에서 선택?

SQL

어떻게 Laravel 쿼리 빌더를 사용하여 하위 쿼리에서 선택?

나는 웅변 ORM을 사용하여 다음 SQL에서 값을 좀하고 싶습니다.

- SQL

 SELECT COUNT(*) FROM 
 (SELECT * FROM abc GROUP BY col1) AS a;

그럼 다음을 고려했다.

- 코드

 $sql = Abc::from('abc AS a')->groupBy('col1')->toSql();
 $num = Abc::from(\DB::raw($sql))->count();
 print $num;

나는 더 나은 솔루션을 찾고 있어요.

간단한 방법을 가르쳐주세요.

해결법

  1. ==============================

    1.@의 delmadord의 대답과 댓글 외에도 :

    @의 delmadord의 대답과 댓글 외에도 :

    수동 필요한 경우, 다음, 당신은 모든 바인딩을 병합합니다 원시 문을 사용할 필요가 있으므로 현재 FROM 절에 서브 쿼리를 만들 수있는 방법은 없다 :

    $sub = Abc::where(..)->groupBy(..); // Eloquent Builder instance
    
    $count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
        ->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder
        ->count();
    

    마음 당신은 올바른 순서로 병합 바인딩 할 필요가있다. 다른 바운드 조항이있는 경우 mergeBindings 후에 넣어야합니다 :

    $count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
    
        // ->where(..) wrong
    
        ->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder
    
        // ->where(..) correct
    
        ->count();
    
  2. ==============================

    2.Laravel의 v5.6.12 (2018년 3월 14일는) fromSub ()와 fromRaw () 쿼리 빌더 (# 23476)에 대한 방법을 추가했습니다.

    Laravel의 v5.6.12 (2018년 3월 14일는) fromSub ()와 fromRaw () 쿼리 빌더 (# 23476)에 대한 방법을 추가했습니다.

    허용 대답은 올바르지 만에 간단하게 할 수 있습니다 :

    DB::query()->fromSub(function ($query) {
        $query->from('abc')->groupBy('col1');
    }, 'a')->count();
    

    위의 조각은 다음과 같은 SQL을 생성합니다 :

    select count(*) as aggregate from (select * from `abc` group by `col1`) as `a`
    
  3. ==============================

    3.@JarekTkaczyk의 솔루션은 내가 찾고 있었던 정확하게 것입니다. 유일한 것은 내가 미스는 당신이 사용하는 경우이 작업을 수행하는 방법 DB :: 테이블 () 쿼리. 이 경우, 이것은 내가 그것을 할 방법입니다 :

    @JarekTkaczyk의 솔루션은 내가 찾고 있었던 정확하게 것입니다. 유일한 것은 내가 미스는 당신이 사용하는 경우이 작업을 수행하는 방법 DB :: 테이블 () 쿼리. 이 경우, 이것은 내가 그것을 할 방법입니다 :

    $other = DB::table( DB::raw("({$sub->toSql()}) as sub") )->select(
        'something', 
        DB::raw('sum( qty ) as qty'), 
        'foo', 
        'bar'
    );
    $other->mergeBindings( $sub );
    $other->groupBy('something');
    $other->groupBy('foo');
    $other->groupBy('bar');
    print $other->toSql();
    $other->get();
    

    어떻게 getQuery를 사용하지 않고 mergeBindings을 만드는 특별 하 atention () 메소드

  4. ==============================

    4.laravel 5.5에서 하위 쿼리를위한 전용 방법이있다 그리고 당신은 다음과 같이 사용할 수 있습니다 :

    laravel 5.5에서 하위 쿼리를위한 전용 방법이있다 그리고 당신은 다음과 같이 사용할 수 있습니다 :

    ABC 방송 :: selectSub (기능 ($ Q) {$ Q-> ( '*')를 선택 -> GROUPBY ( 'COL1을');}, 'A') -> 수 ( 'A *.');

    또는

    ABC 방송 :: selectSub가 (ABC가 ::) '*'(선택 -> GROUPBY ( 'COL1')을, 'A') -> 수 ( 'A *.');

  5. ==============================

    5.이 같은 일을 좋아한다 :

    이 같은 일을 좋아한다 :

    Message::select('*')
    ->from(DB::raw("( SELECT * FROM `messages`
                      WHERE `to_id` = ".Auth::id()." AND `isseen` = 0
                      GROUP BY `from_id` asc) as `sub`"))
    ->count();
    

    아주 우아한 아니지만, 그것은 간단합니다.

  6. ==============================

    6.내가 원하는 쿼리를 수행하는 코드를 만들 수없는 경우, AS는하지 파생 테이블 만 테이블 ABC의 별칭이다. Laravel 쿼리 빌더는 암시 적으로 파생 테이블 별칭을 지원하지 않습니다, DB :: 원료는 대부분이 필요합니다.

    내가 원하는 쿼리를 수행하는 코드를 만들 수없는 경우, AS는하지 파생 테이블 만 테이블 ABC의 별칭이다. Laravel 쿼리 빌더는 암시 적으로 파생 테이블 별칭을 지원하지 않습니다, DB :: 원료는 대부분이 필요합니다.

    내가 생각 해낸 수있는 가장 직선 솔루션은 그러나 당신이 요청으로 쿼리를 생성, 당신과 거의 동일합니다 :

    $sql = Abc::groupBy('col1')->toSql();
    $count = DB::table(DB::raw("($sql) AS a"))->count();
    

    생성 된 쿼리는

    select count(*) as aggregate from (select * from `abc` group by `col1`) AS a;
    
  7. ==============================

    7.올바른 방법은이 답변에 설명 : https://stackoverflow.com/a/52772444/2519714 현재의 순간에 가장 인기있는 대답은 완전히 정확하지 않습니다.

    올바른 방법은이 답변에 설명 : https://stackoverflow.com/a/52772444/2519714 현재의 순간에 가장 인기있는 대답은 완전히 정확하지 않습니다.

    이 방법 https://stackoverflow.com/a/24838367/2519714 같은 경우에 올바르지 않습니다 : 서브 바인딩, 하위에 다음에 합류 테이블 후, 모든 쿼리에 추가 된 다른 알의를 선택한 경우이 선택합니다. 예를 들어 쿼리 : * 선택에서 COL1 = COL2 = COL3 및 T2에 가입 (T1 COL1 =?를 선택 *)? 여기서 t2.col4 =를? 당신이 좋아하는 코드를 작성하는 것이 쿼리를 만들려면 :

    $subQuery = DB::query()->from('t1')->where('t1.col1', 'val1');
    $query = DB::query()->from(DB::raw('('. $subQuery->toSql() . ') AS subquery'))
        ->mergeBindings($subQuery->getBindings());
    $query->join('t2', function(JoinClause $join) {
        $join->on('subquery.col1', 't2.col2');
        $join->where('t2.col3', 'val3');
    })->where('t2.col4', 'val4');
    

    대신에 올바른 [ 'val1과', 'val3', 'val4이 경우에는 ['val3 ','val1과 ','val4 ']처럼 잘못된 순서로 바인딩을 반환이 쿼리를 실행, 자신의 방법 $ 질의 -> getBindings ()시 '] 원료 SQL 대해 상술.

    한 번 더 올바른 방법은이 작업을 수행합니다 :

    $subQuery = DB::query()->from('t1')->where('t1.col1', 'val1');
    $query = DB::query()->fromSub($subQuery, 'subquery');
    $query->join('t2', function(JoinClause $join) {
        $join->on('subquery.col1', 't2.col2');
        $join->where('t2.col3', 'val3');
    })->where('t2.col4', 'val4');
    

    또한 바인딩이 자동으로 올바르게 새 쿼리에 병합됩니다.

  8. from https://stackoverflow.com/questions/24823915/how-to-select-from-subquery-using-laravel-query-builder by cc-by-sa and MIT license