IT

LEFT JOIN의 LIMIT 사용방법

itgroup 2023. 1. 15. 17:02
반응형

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

반응형