sql >> Databasteknik >  >> RDS >> Mysql

FIND_IN_SET() vs IN()

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

attachedCompanyIDs är ett skalärt värde som gjuts in i INT (typ av companyID ).

Medverkande returnerar bara nummer upp till den första icke-siffran (ett kommatecken i ditt fall).

Alltså

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

I PostgreSQL , du kan gjuta strängen till array (eller lagra den som en array i första hand):

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

och detta skulle till och med använda ett index på companyID .

Tyvärr fungerar detta inte i MySQL eftersom den senare inte stöder arrayer.

Du kanske tycker att den här artikeln är intressant (se #2 ):

Uppdatering:

Om det finns någon rimlig gräns för antalet värden i de kommaseparerade listorna (säg inte mer än 5 ), så du kan försöka använda den här frågan:

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)


  1. mysqli:kan det förbereda flera frågor i ett uttalande?

  2. Grundläggande revisionstabell för Oracle Trigger

  3. Exportera tabell till fil med kolumnrubriker (kolumnnamn) med hjälp av bcp-verktyget och SQL Server 2008

  4. Hur man inaktiverar en CHECK-begränsning i SQL Server (T-SQL-exempel)