Laavel 쿼리 생성기의 하위 쿼리(부 쿼리)에 대한 쓰기

12727 단어 LaravelPHP
첫 투고.비록 나는 아직 초보 엔지니어이지만, 나는 업무 중에 laavel을 사용하여 개발을 진행했다.
대상 버전(작업 확인 완료)은 5.1입니다.
DB는 Postgresql9입니다.4.4 사용했습니다.
설명에서는 Enloquent ORM을 사용하지 않지만 사용 후에도 계속 작동합니다.
laravel을 사용하기 시작한 지 2년째인데 부제를 어떻게 써야 할지 고민이었다.
문서를 봤는데 exsist 문장에서만 하위 검색을 언급했습니다.
그래서 where 문장과where in 문장에 사용할 수 있는 상황을 소개해 드리겠습니다.

데이터 준비


최근 열광하고 있는 애니메이션'건물매! 매립'을 예로 들자.
동생 S는 가라오케에 가서 이런 데이터를 준비해 봤다.
동생 S 메시지가 담긴 책상
sisters
 id |          name          
----+------------------------
  1 | 土間うまる
  2 | 海老名菜々
  3 | 本場切絵
  4 | 橘・シルフィンフォード
누가 어떤 노래를 불렀는지 기록하는 테이블.
musics
 id | sistersid |              title              
----+-----------+---------------------------------
  1 |         1 | かくしん的☆めたまるふぉ~ぜっ!
  2 |         2 | かくしん的☆めたまるふぉ~ぜっ!
  3 |         3 | かくしん的☆めたまるふぉ~ぜっ!
  4 |         4 | かくしん的☆めたまるふぉ~ぜっ!
  5 |         1 | ひだまりデイズ
  6 |         2 | ひだまりデイズ
  7 |         3 | ひだまりデイズ
  8 |         4 | ひだまりデイズ
  9 |         1 | 勇者うまるの華麗なる生活
 10 |         2 | そいだばね
 11 |         3 | My Precious
 12 |         4 | T・S・F in にっぽん!
 13 |         1 | Beautiful Days
 14 |         2 | sweet sweet everytime sweet
 15 |         3 | トトファンタジア
 16 |         4 | シュバッとNo.1
 17 |         1 | Sisters Wink
 18 |         2 | Sisters Wink
 19 |         3 | Sisters Wink
 20 |         4 | Sisters Wink
곡과 득점, 그리고 몇 바퀴째 테이블을 기록합니다.
네 사람이 다 부르고 한 바퀴만 돌았다.
scores
 id | musicsid | score | turn 
----+----------+-------+------
  1 |        1 |    80 |    1
  2 |        2 |    95 |    1
  3 |        3 |    70 |    1
  4 |        4 |    64 |    1
  5 |        5 |    50 |    2
  6 |        6 |    73 |    2
  7 |        7 |    30 |    2
  8 |        8 |    84 |    2
  9 |        9 |    90 |    3
 10 |       10 |   100 |    3
 11 |       11 |    33 |    3
 12 |       12 |    55 |    3
 13 |       13 |    47 |    4
 14 |       14 |    91 |    4
 15 |       15 |    92 |    4
 16 |       16 |     0 |    4
 17 |       17 |    90 |    5
 18 |       18 |    89 |    5
 19 |       19 |    84 |    5
 20 |       20 |    56 |    5
하위 조회를 사용해야만 얻을 수 있는 데이터 구조입니다.
그렇다면 위의 데이터에서'순환마다 누가 가장 높은 점수를 받았고 어떤 노래를 불렀는가'를 얻었다.
나는 SQL문이 이렇다고 생각한다.
sql
select s.turn, si.name, mu.title, s.score from scores s 
inner join musics mu on s.musicsid = mu.id 
inner join sisters si on si.id = mu.sistersid
where (s.turn, s.score) in (select turn, max(score) from scores group by turn);
일단 이거 놓고 결과를 확인해 보자.
결실
 turn |          name         |              title              | score 
------+-----------------------+---------------------------------+-------
    1 | 海老名菜々             | かくしん的☆めたまるふぉ~ぜっ!  |    95
    2 | 橘・シルフィンフォード  | ひだまりデイズ           |    84
    3 | 海老名菜々             | そいだばね             |   100
    4 | 本場切絵               | トトファンタジア                 |    92
    5 | 土間うまる             | Sisters Wink                    |    90
문제 없을 것 같습니다.

그럼


where 문장과where in 문장의 하위 조회 쓰기 방법은 우선 각자의 방법의 내용을 살펴보자.
  • where
  • Illuminate/Database/Query/Builder.php
        /**
         * Add a basic where clause to the query.
         *
         * @param  string|array|\Closure  $column
         * @param  string  $operator
         * @param  mixed   $value
         * @param  string  $boolean
         * @return $this
         *
         * @throws \InvalidArgumentException
         */
        public function where($column, $operator = null, $value = null, $boolean = 'and')
        {
            // 中略
    
            // If the value is a Closure, it means the developer is performing an entire
            // sub-select within the query and we will need to compile the sub-select
            // within the where clause to get the appropriate query record results.
            if ($value instanceof Closure) {
                return $this->whereSub($column, $operator, $value, $boolean);
            }
    
    
  • whereIn
  • Illuminate/Database/Query/Builder.php
        /**
         * Add a "where in" clause to the query.
         *
         * @param  string  $column
         * @param  mixed   $values
         * @param  string  $boolean
         * @param  bool    $not
         * @return $this
         */
        public function whereIn($column, $values, $boolean = 'and', $not = false)
        {
            $type = $not ? 'NotIn' : 'In';
    
            // If the value of the where in clause is actually a Closure, we will assume that
            // the developer is using a full sub-select for this "in" statement, and will
            // execute those Closures, then we can re-construct the entire sub-selects.
            if ($values instanceof Closure) {
                return $this->whereInSub($column, $values, $boolean, $not);
            }
    
            //省略
    
    
    
    각각 방법에 복제자가 교부되었을 때의 처리라고 쓰여 있다.
    그래서 모자간을 이용하면 돼요!
    아마도 더 좋은 작법이 있을 것이다. 바로 이런 느낌이다.
    app/umr.php
    
        public function getKaraokeResult()
        {
            return DB::table('scores as s')->select('s.turn', 'si.name', 'mu.title', 's.score')
                                           ->join('musics as mu', 'mu.id', '=', 's.musicsid')
                                           ->join('sisters as si', 'si.id', '=', 'mu.sistersid')
                                           ->whereIn(DB::raw('(s.turn, s.score)'), 
                                               function ($query) 
                                               {
                                                   $query->select('turn', DB::raw('max(score)'))
                                                         ->from('scores')
                                                         ->groupBy('turn');
                                               })
                                           ->get();
        }
    
    
    
    whereIn () 은 여러 열을 지원하지 않기 때문에 일부 raw () 를 사용하여 직접 씁니다.
    이raw()와closer의 조합을 통해 더 복잡한 SQL문도 조회 생성기로 쓸 수 있다고 생각합니다.
    또한 표의 별명에 관해서는 as를 생략하면 오류가 발생할 수 있습니다.
    그것은 주제 밖의 말이다
    Eloquent의 softdelete를 사용하면 "deleted at is null"은 자동으로 추가되지만 마스크 내 질의와는 상호 보완되지 않습니다.
    그러면 실행하기 전에 생성된 SQL 문을 toSql()로 확인합니다.
    이 방법을 사용하면 발매된 SQL문을 알 수 있어 매우 편리하다.

    아까의 SQL 문구와 같은 형식으로 잘 변했네요.
    실행, 확인.

    SQL을 넣었을 때와 마찬가지로 같은 결과를 얻었다.

    총결산하다

  • 복제자를 where 문장where in 문장
  • 에 전달할 수 있음
  • DB::raw()를 병용하여 복잡한 SQL 문장을 쓸 수 있음
  • 해로명은 노래를 잘한다(웃음)
    (점수가 잘 맞아서 우연이야!)
  • 지적하고 더 좋은 방법이 있는 사람은 반드시 메시지를 남겨주세요.

    좋은 웹페이지 즐겨찾기