programing

FIND_IN_SET() vs IN()

goodsources 2023. 2. 2. 21:13
반응형

FIND_IN_SET() vs IN()

데이터베이스에 테이블이 2개 있습니다.하나는 주문용이고 다른 하나는 회사용입니다.

주문의 구조는 다음과 같습니다.

OrderID     |     attachedCompanyIDs
------------------------------------
   1                     1,2,3
   2                     2,4

Company의 구조는 다음과 같습니다.

CompanyID      |        name
--------------------------------------
    1                 Company 1
    2                 Another Company
    3                 StackOverflow
    4                 Nothing

주문의 회사 이름을 얻으려면 다음과 같이 문의할 수 있습니다.

SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)

이 쿼리는 정상적으로 동작하지만 다음 쿼리는 동작하지 않습니다.

SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)

첫 번째 쿼리는 동작하지만 두 번째 쿼리는 동작하지 않는 이유는 무엇입니까?

첫 번째 쿼리는 다음을 반환합니다.

name
---------------
Company 1
Another Company
StackOverflow

두 번째 쿼리는 다음 항목만 반환합니다.

name
---------------
Company 1

첫 번째 쿼리는 모든 회사를 반환하고 두 번째 쿼리는 첫 번째 쿼리만 반환하는 이유는 무엇입니까?

SELECT  name
FROM    orders,company
WHERE   orderID = 1
        AND companyID IN (attachedCompanyIDs)

attachedCompanyIDs스칼라 값입니다.INT(종류companyID).

캐스트는 첫 번째 숫자가 아닌 숫자(이 경우 쉼표)까지만 반환합니다.

따라서,

companyID IN ('1,2,3') ≡ companyID IN (CAST('1,2,3' AS INT)) ≡ companyID IN (1)

PostgreSQL, 문자열을 배열에 캐스트(또는 애초에 배열로 저장)할 수 있습니다.

SELECT  name
FROM    orders
JOIN    company
ON      companyID = ANY (('{' | attachedCompanyIDs | '}')::INT[])
WHERE   orderID = 1

그리고 이것은 심지어 지표를 사용할 것이다.companyID.

아쉽게도 이 기능은 에서는 동작하지 않습니다.MySQL후자는 어레이를 지원하지 않기 때문입니다.

이 기사가 흥미로울 수 있습니다( 참조).#2):

업데이트:

쉼표로 구분된 목록의 값 수에 대한 합리적인 제한이 있는 경우(예:5)를 사용하면 다음 쿼리를 사용할 수 있습니다.

SELECT  name
FROM    orders
CROSS JOIN
        (
        SELECT  1 AS pos
        UNION ALL
        SELECT  2 AS pos
        UNION ALL
        SELECT  3 AS pos
        UNION ALL
        SELECT  4 AS pos
        UNION ALL
        SELECT  5 AS pos
        ) q
JOIN    company
ON      companyID = CAST(NULLIF(SUBSTRING_INDEX(attachedCompanyIDs, ',', -pos), SUBSTRING_INDEX(attachedCompanyIDs, ',', 1 - pos)) AS UNSIGNED)

접속 회사ID는 하나의 큰 문자열이기 때문에 mysql은 company를 정수로 캐스트합니다.

사용 장소

따라서 comapnyid = 1인 경우:

companyID IN ('1,2,3')

이것은 사실로 반환된다.

숫자 1이 1이 아니면

 companyID IN ('2,3,1')

그 반환은 거짓이다.

특정 ID를 기반으로 하지 않고 모든 관련 회사 이름을 가져옵니다.

SELECT 
    (SELECT GROUP_CONCAT(cmp.cmpny_name) 
    FROM company cmp 
    WHERE FIND_IN_SET(cmp.CompanyID, odr.attachedCompanyIDs)
    ) AS COMPANIES
FROM orders odr

두 번째 쿼리는 ID가 1 또는 2 또는 3인 행을 찾기 때문에 첫 번째 쿼리는 회사에 존재하는 쉼표로 구분된 값 중 하나를 찾습니다.아이디,

여기서 또 다른 문제는 = count(table1) * count(table2) 행이 변환된다는 것입니다.

당신의 문제는 제 답변의 파트 2에 정말로 존재합니다.(두 번째 질문으로)

언급URL : https://stackoverflow.com/questions/4155873/find-in-set-vs-in

반응형