BUSCAR EN SET () vs EN()


Tengo 2 tablas en mi base de datos. Una es para pedidos, y la otra es para empresas.

Orders tiene esta estructura:

OrderID     |     attachedCompanyIDs
------------------------------------
   1                     1,2,3
   2                     2,4

Y la Compañía tiene esta estructura:

CompanyID      |        name
--------------------------------------
    1                 Company 1
    2                 Another Company
    3                 StackOverflow
    4                 Nothing

Para obtener los nombres de las empresas de un pedido, puedo hacer una consulta como tal:

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

Esa consulta funciona bien, pero la siguiente no.

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

¿Por qué funciona la primera consulta pero no la segunda?

La primera consulta devuelve:

name
---------------
Company 1
Another Company
StackOverflow

La segunda consulta solamente devuelve:

name
---------------
Company 1

¿Por qué es esto, por qué la primera consulta devuelve todas las empresas, pero la segunda consulta solo devuelve la primera?

 112
Author: Rocket Hazmat, 2010-11-11

7 answers

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

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

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

Así,

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

En PostgreSQL, puedes convertir la cadena en un array (o almacenarla como un array 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 soporta arrays.

Usted puede encontrar esto artículo interesante (ver #2):

Actualización:

Si hay algún límite razonable en el número de valores en las listas separadas por comas (por ejemplo, no más de 5), puede intentar usar 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)
 87
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-07 16:59:44

AttachedCompanyIDs es una cadena grande, por lo que mysql intenta encontrar compañía en este su fundido a entero

Cuando se utiliza donde en

Así que si comapnyid = 1:

companyID IN ('1,2,3')

Esto es return true

Pero si el número 1 no está en primer lugar

 companyID IN ('2,3,1')

Su retorno falso

 9
Author: Haim Evgi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 15:23:52

Para obtener el nombre de todas las empresas relacionadas, no basado en una identificación particular.

SELECT 
    (SELECT GROUP_CONCAT(cmp.cmpny_name) 
    FROM company cmp 
    WHERE FIND_IN_SET(cmp.CompanyID, odr.attachedCompanyIDs)
    ) AS COMPANIES
FROM orders odr
 3
Author: Anupriya Pundir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-16 08:12:23

Porque la segunda consulta está buscando filas con los id's 1, 2 O 3, la primera consulta está buscando uno de los valores delimitados por comas que existen en CompanyId,

Y otro problema aquí es que no está uniendo las tablas en una clave común en su donde, por lo que va a obtener una mutación de filas que = count (table1) * count (table2);

Su problema realmente existe con la parte 2 de mi respuesta. (con su segunda consulta)

 1
Author: superfro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-11 15:23:09

Permítanme explicar cuándo usar FIND_IN_SET y Cuándo usar IN.

Tomemos la tabla A que tiene columnas llamadas "aid","aname". Tomemos la tabla B que tiene columnas llamadas "bid","bname", "aids".

Ahora hay valores ficticios en la Tabla A y la Tabla B como se muestra a continuación.

Cuadro A

Aid aname

1 Manzana

2 Banana

3 Mango

Cuadro B

Bid bname aids

1 Manzana 1,2

2 Plátano 2,1

3 Mango 3,1,2

enter code here

Case1: si desea obtener esos registros de la tabla b que tiene 1 valor presente en las columnas de ayudas, entonces debe usar FIND_IN_SET.

Consulta: seleccione * de UNA COMBINACIÓN B EN FIND_IN_SET(A. aid,b.aids) donde A. aid = 1;

Case2: si desea obtener esos registros de la tabla a que tiene 1 O 2 O 3 valor presente en las columnas de ayuda, entonces tiene que usar EN.

Consulta: seleccione * de A JOIN B ON A. aid IN (b. aids);

Ahora aquí hasta que lo que necesidades a través de mysql query.

 -1
Author: prashant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 05:37:03

Filtrar desde la columna separada por comas en MySQL usando find_in_set

select * from vendor_profile_pages where FIND_IN_SET('3', service_title_id);
 -1
Author: Jasim Juwel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-24 10:16:21
SELECT o.*, GROUP_CONCAT(c.name) FROM Orders AS o , Company.c
    WHERE FIND_IN_SET(c.CompanyID , o.attachedCompanyIDs) GROUP BY o.attachedCompanyIDs
 -2
Author: amit gangrade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-21 07:14:22