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문이 이렇다고 생각한다.
sqlselect 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 문장의 하위 조회 쓰기 방법은 우선 각자의 방법의 내용을 살펴보자.
id | name
----+------------------------
1 | 土間うまる
2 | 海老名菜々
3 | 本場切絵
4 | 橘・シルフィンフォード
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
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
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 문장의 하위 조회 쓰기 방법은 우선 각자의 방법의 내용을 살펴보자.
/**
* 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);
}
/**
* 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을 넣었을 때와 마찬가지로 같은 결과를 얻었다.
총결산하다
(점수가 잘 맞아서 우연이야!)
Reference
이 문제에 관하여(Laavel 쿼리 생성기의 하위 쿼리(부 쿼리)에 대한 쓰기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/PG_marbo/items/b8ac349ff81b4fa753a6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)