sql >> Base de Datos >  >> RDS >> Mysql

FIND_IN_SET() frente a IN()

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

attachedCompanyIDs es un valor escalar que se convierte en INT (tipo de companyID ).

El elenco solo devuelve números hasta el primer dígito que no sea (una coma en su caso).

Así,

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

En PostgreSQL , podría convertir la cadena en una matriz (o almacenarla como una matriz en primer lugar):

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

y esto incluso usaría un índice en companyID .

Desafortunadamente, esto no funciona en MySQL ya que este último no admite matrices.

Puede encontrar este artículo interesante (ver #2 ):

Actualización:

Si existe algún límite razonable en el número de valores en las listas separadas por comas (por ejemplo, no más de 5 ), por lo que puede intentar utilizar esta consulta:

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)