개요:
프로젝트에는 복잡한 SQL 대역 서브쿼리가 많이 사용되는데, Laravel의 쿼리 빌더는 직접 서브쿼리로 변환하는 방법을 제공하지 않거나, 방법을 제공하지만 구체적인 예를 제시하지 못해 초보자에게는 매우 불친절합니다. 이 장에서는 Laravel이 서브쿼리가 있는 SQL을 어떻게 구성하는지 주로 이야기합니다.
준비:
우선, 라라벨은 일반적으로 서브쿼리의 두 가지 방식을 구현하고 있습니다.
1, toSql()+getQuery()+raw() 방법:
1.tosql() 메서드는 binding 매개 변수가 없는 SQL, 즉 물음표가 붙은 SQL을 얻기 위한 역할을 한다.
select * from `rooms` where `rooms`.`project_id` = ?
1.getQuery() 방법은 binding 파라미터를 얻고 tosql() 대신 SQL 물음표를 획득하여 완전한 SQL을 얻기 위한 것입니다
select * from `rooms` where `rooms`.`project_id` = 3
1.raw( )는 Laravel의 쿼리 빌더에 SQL을 직접 끼우는 역할을 합니다
`$sql = 'select * from `rooms` where `rooms`.`project_id` = 3';
$resultSql = DB::table('DB::raw($sql as room')->toSql();`
그러면 SQL을 획득할 수 있습니다
select * from (select * from `rooms` where `rooms`.`project_id` = 3) as room
주의: SQL을 직접 사용하는 것은 raw()뿐만 아니라 whereRaw()
2, 쿼리 빌더를 사용하여 일부 자체적인 폐쇄형 패킷
예를 들어:
User::whereIn('id', function($query){
$query->select('user_id')
->from('admin_user')
->whereIn('type', ['1', '2']);
})->get();
얻을 수 있는 SQL:
select * from `user` where `id` in (select `user_id` from `admin_user` where `type` in (1, 2));
이와 같은 폐쇄형 서브쿼리 구현에는 whereExists, where 등이 있다.
예:
PHP 코드:
$ipCountObject = new \Model\BlacklistIpCountDate();
$ipCountObj = $ipCountObject->selectRaw("sum(attack_count) AS attack_times, ip")->where('attack_count', '>', '0')->whereBetween('data', ['2017-10-10', '2017-10-11'])->groupBy('ip');
$totalObj = DB::table( DB::raw("({$ipCountObj->toSql()}) as sub, blacklist_attack_ip"))->mergeBindings($ipCountObj->getQuery())->select('attack_ip', 'country', 'province', 'city', 'line', 'info_update_time AS attack_time', 'attack_times'); //toSql获得的sql有?,需要填入变量
$totalObj = $totalObj->where('blacklist_attack_ip.attack_ip', '=', 'sub.ip')->get();
SQL 획득 가능:
SELECT
`attack_ip`,
`country`,
`province`,
`city`,
`line`,
`info_update_time` AS `attack_time`,
`attack_times`
FROM
( SELECT sum( attack_count ) AS attack_times, ip FROM `blacklist_ip_count_date` WHERE `attack_count` > 0 AND `date` BETWEEN '2017-10-10' AND '2017-10-11' GROUP BY `ip` ) AS sub,
blacklist_attack_ip
WHERE
`blacklist_attack_ip`.`attack_ip` = `sub`.`ip`
요약:
이 두 가지 방법을 모두 활용해야 한다. 첫 번째 방법은 기본적으로 하위 쿼리에 공통적으로 적용되며, 두 번째 방법은 where와 관련된 위치에만 적용됩니다.물론 개인적인 조언은 획일적이다. 만약 당신이 프로젝트에 첫 번째를 사용한다면, 당신은 where의 하위 조회도 첫 번째의 편리함을 고수해야 한다.이 외에도 Laravel 쿼리 빌더는 join, lefeJoin, rightJoin 등 다른 클로즈드 패킷을 제공하지만, 이러한 클로즈드 패킷은 개별 테스트 결과 하위 쿼리를 구현하지 못합니다.
'개발 꿀팁 > PHP' 카테고리의 다른 글
codeigniter의 Redis 사용 (0) | 2022.08.04 |
---|---|
Nginx + PHP-fpm File not found. 문제 해결 기록 (0) | 2022.08.04 |
php에서 중국어 문자열을 어떻게 잘라내나요? (0) | 2022.08.03 |
8가지 필수 PHP 기능 개발 (0) | 2022.08.03 |
PHP 인용자 & 용법 상세 분석 (0) | 2022.08.03 |