FIND_IN_SET () 대 IN ()
데이터베이스에 2 개의 테이블이 있습니다. 하나는 주문을위한 것이고 다른 하나는 회사를위한 것입니다.
주문의 구조는 다음과 같습니다.
OrderID | attachedCompanyIDs
------------------------------------
1 1,2,3
2 2,4
그리고 회사는 다음과 같은 구조를 가지고 있습니다 :
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)
attachedCompanyIDs는 하나의 큰 문자열이므로 mysql은 정수로 캐스팅 된 회사를 찾으려고합니다.
어디에서 사용할 때
따라서 comapnyid = 1 인 경우 :
companyID IN ('1,2,3')
이것은 사실이다
그러나 숫자 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 OR 3 인 행을 찾기 때문에 첫 번째 쿼리는 companyID에 존재하는 쉼표로 구분 된 값 중 하나를 찾고 있습니다.
and another problem here is you aren't joining the tables on a common key in your where so you are going to get a mutation of rows that = count(table1) * count(table2);
Your problem really exists with part 2 of my answer. (with your second query)
Let me explain when to use FIND_IN_SET and When to use IN.
Let's take table A which has columns named "aid","aname". Let's take table B which has columns named "bid","bname","aids".
Now there are dummy values in Table A and Table B as below.
Table A
aid aname
1 Apple
2 Banana
3 Mango
Table B
bid bname aids
1 Apple 1,2
2 Banana 2,1
3 Mango 3,1,2
enter code here
Case1: if you want to get those records from table b which has 1 value present in aids columns then you have to use FIND_IN_SET.
Query: select * from A JOIN B ON FIND_IN_SET(A.aid,b.aids) where A.aid = 1 ;
Case2: if you want to get those records from table a which has 1 OR 2 OR 3 value present in aid columns then you have to use IN.
Query: select * from A JOIN B ON A.aid IN (b.aids);
Now here upto you that what you needs through mysql query.
SELECT o.*, GROUP_CONCAT(c.name) FROM Orders AS o , Company.c
WHERE FIND_IN_SET(c.CompanyID , o.attachedCompanyIDs) GROUP BY o.attachedCompanyIDs
참고URL : https://stackoverflow.com/questions/4155873/find-in-set-vs-in
'Programming' 카테고리의 다른 글
size_t와 std :: size_t의 차이점 (0) | 2020.07.14 |
---|---|
Python에서 WSDL (SOAP) 웹 서비스를 사용하려면 어떻게해야합니까? (0) | 2020.07.14 |
명령 프롬프트에서 응용 프로그램을“관리자 권한으로 실행”하는 방법은 무엇입니까? (0) | 2020.07.14 |
REST API 토큰 기반 인증 (0) | 2020.07.14 |
Python 3의 Concurrent.futures vs 멀티 프로세싱 (0) | 2020.07.14 |