Mysql
 sql >> Datenbank >  >> RDS >> Mysql

FIND_IN_SET() vs. IN()

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

attachedCompanyIDs ist ein Skalarwert, der in INT gecastet wird (Art der companyID ).

Die Umwandlung gibt nur Zahlen bis zur ersten Nicht-Ziffer (in Ihrem Fall ein Komma) zurück.

Also

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

In PostgreSQL , könnten Sie den String in ein Array umwandeln (oder ihn überhaupt als Array speichern):

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

und dies würde sogar einen Index auf companyID verwenden .

Leider funktioniert dies nicht in MySQL da letzteres keine Arrays unterstützt.

Dieser Artikel könnte für Sie interessant sein (siehe #2 ):

Aktualisierung:

Wenn es eine vernünftige Grenze für die Anzahl der Werte in den durch Kommas getrennten Listen gibt (z. B. nicht mehr als 5 ), also können Sie versuchen, diese Abfrage zu verwenden:

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)