Mysql
 sql >> Database >  >> RDS >> Mysql

FIND_IN_SET() vs IN()

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

attachedCompanyIDs è un valore scalare che viene lanciato in INT (tipo di companyID ).

Il cast restituisce solo numeri fino alla prima non cifra (una virgola nel tuo caso).

Quindi,

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

In PostgreSQL , puoi eseguire il cast della stringa nell'array (o archiviarla come array in primo luogo):

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

e questo userebbe anche un indice su companyID .

Sfortunatamente, questo non funziona in MySQL poiché quest'ultimo non supporta gli array.

Potresti trovare interessante questo articolo (vedi #2 ):

Aggiornamento:

Se esiste un limite ragionevole al numero di valori negli elenchi separati da virgole (ad esempio, non più di 5 ), quindi puoi provare a utilizzare questa query:

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)