LEFT JOIN의 LIMIT 사용방법
테이블이 두 개 있어요categories
그리고.products
이 관계를 통해:
categories.category_id
=products.product_category_id
2개의 상품으로 모든 카테고리를 보여주고 싶다!
[
[category 1] =>
[
'category_id' => 1,
'category_title' => 'category_title 1',
[products] => [
'0' => [
'product_category_id' => 1,
'product_id' => 51,
'product_title' => 'product_title 1',
],
'1' => [
'product_category_id' => 1,
'product_id' => 55,
'product_title' => 'product_title 2',
]
]
],
[category 2] =>
[
'category_id' => 2,
'category_title' => 'category_title 2',
[products] => [
'0' => [
'product_category_id' => 2,
'product_id' => 32,
'product_title' => 'product_title 3',
],
'1' => [
'product_category_id' => 2,
'product_id' => 33,
'product_title' => 'product_title 4',
]
]
],
...
]
나는 Laravel 웅변가로서 다음과 같은 것을 사용할 수 있다.
$categories = Category::with(['products' => function($q) {
$q->limit(2)
}])->get();
하지만 저는 Larabel을 사용하지 않고 순수한 SQL 코드가 필요합니다!이 코드를 사용해 보았습니다.
SELECT
CT.category_id,
PT.product_category_id,
CT.category_title,
PT.product_id,
PT.product_title
FROM
categories CT
LEFT JOIN(
SELECT
*
FROM
products
LIMIT 2
) AS PT
ON
CT.category_id = PT.product_category_id
WHERE
CT.category_lang = 'en'
하지만 이 코드에는 문제가 있습니다!MYSQL은 처음에 2개의 첫 번째 행이 있는 것 같습니다.products
테이블과 테이블에서LEFT JOIN
부터categories
그 2열로! 그리고 이 원인은 다시 돌아옵니다.null
제품의 값(단, 삭제한 경우)LIMIT
잘 작동하지만, 저는LIMIT
)
이 코드도 테스트했습니다.(갱신 완료)
SELECT
CT.category_id,
PT.product_category_id,
CT.category_title,
PT.product_id,
PT.product_title
FROM
categories CT
LEFT JOIN(
SELECT
*
FROM
products
WHERE
product_category_id = CT.category_id
LIMIT 5
) AS PT
ON
CT.category_id = PT.product_category_id
WHERE
CT.category_lang = 'en'
하지만 다음 오류가 발생했습니다.
1054 - 'where 절'의 알 수 없는 열 'CT.category_id'
에 접속할 수 없다CT.category_id
서브쿼리에서요.
가장 좋은 해결책은 무엇인가?
MySQL에서는 변수를 사용해야 합니다.기본 개념은 다음과 같습니다.
select p.*
from (select p.*,
(@rn := if(@c = product_category_id, @rn + 1,
if(@c := product_category_id, 1, 1)
)
) as rn
from (select p.*
from products p
order by p.product_category_id
) p cross join
(select @c := -1, @rn := 0) params
) p
where rn <= 2;
이를 하위 쿼리로 사용한 다음 나머지 카테고리 정보에 참여할 수 있습니다.
이 코드가 동작하는 경우의 db<>fiddle을 나타냅니다.
MySQL 8+/MariaDB 10.2+에서는 다음과 같이 쉽게 기술됩니다.
select p.*
from (select p.*,
row_number() over (partition by product_category_id order by product_category_id) as seqnum
from products p
) p
where seqnum <= 2;
주의: 원하는 2개의 제품(예: 처음 두 개)을 지정하려면order by
절을 지정합니다.
편집:
MariaDB 10.2에서는 주문에 서브쿼리를 사용할 수 없기 때문에 적절한 쿼리는 다음과 같습니다.
select p.*
from (select p.*,
(@rn := if(@c = product_category_id, @rn + 1,
if(@c := product_category_id, 1, 1)
)
) as rn
from products p cross join
(select @c := -1, @rn := 0) params
order by p.product_category_id
) p
where rn <= 2;
여기 그 db <> fiddle이 있습니다.
다음 방법도 사용할 수 있습니다.
select p.*
from products p
where (select count(*)
from products p2
where p2.product_category_id = p.product_category_id and p2.id <= p.id
) <= 2;
이것은 추천하지 않습니다.관련된 서브쿼리는 일반적으로 퍼포먼스가 더 나쁘기 때문입니다.order by
그러나 카테고리별로 상품이 많지 않으면 (적절한 인덱스로) 괜찮습니다.
언급URL : https://stackoverflow.com/questions/53969692/how-to-use-limit-on-left-join
'IT' 카테고리의 다른 글
LUMEN : SQLSTATE [ 42000 ]를 수정하는 방법:구문 오류 또는 액세스 위반: larabel lumen에서 1071 (0) | 2023.01.15 |
---|---|
C 및 C++의 탭 문자를 이스케이프해야 합니까? (0) | 2023.01.15 |
개체를 포함하는 두 어레이를 병합하고 중복된 값을 제거합니다. (0) | 2023.01.12 |
PHP에서 두 날짜를 비교하려면 어떻게 해야 하나요? (0) | 2023.01.12 |
Mariadb 스레드에 '다음 명령에 대해 재설정' 상태가 고착됨 (0) | 2023.01.12 |