Tengo 2 tablas en mi base de datos. Uno es para pedidos y otro para empresas.
Los pedidos tienen esta estructura:
OrderID | attachedCompanyIDs
------------------------------------
1 1,2,3
2 2,4
Y la empresa 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 consulta 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 solo 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?
Respuestas:
attachedCompanyIDs
es un valor escalar que se convierte enINT
(tipo decompanyID
).El reparto solo devuelve números hasta el primer no dígito (una coma en su caso).
Así,
En
PostgreSQL
, puede convertir la cadena en una matriz (o almacenarla como una matriz en primer lugar):y esto incluso usaría un índice en
companyID
.Desafortunadamente, esto no funciona
MySQL
ya que este último no admite matrices.Puede encontrar este artículo interesante (ver
#2
):Actualizar:
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:fuente
FIND_IN_SET
funciona, pero no usa índices, y puede ser lento con mucha información en la tabla Compañía.pos
elementos desde el principioCVS
y convierte el resto en entero.10 things in MySQL (that won’t work as expected)
CROSS JOIN
? ¿No son todos iguales en MySQL?attachCompanyIDs es una gran cadena, por lo que mysql intenta encontrar compañía en este su elenco a entero
cuando usas donde en
entonces si comapnyid = 1:
esto es cierto
pero si el número 1 no está en primer lugar
su retorno falso
fuente
Para obtener el nombre de todas las empresas relacionadas, no se basa en una identificación particular
fuente
debido a que la segunda consulta busca filas con los ID 1 O 2 O 3, la primera consulta busca uno de los valores delimitados por comas que existen en la ID de compañía,
y otro problema aquí es que no está uniendo las tablas en una clave común en su ubicación, por lo que obtendrá una mutación de filas que = cuenta (tabla1) * cuenta (tabla2);
Su problema realmente existe con la parte 2 de mi respuesta. (con su segunda consulta)
fuente
Permítanme explicar cuándo usar FIND_IN_SET y cuándo usar IN.
Tomemos la tabla A que tiene columnas llamadas "ayuda", "aname". Tomemos la tabla B que tiene columnas llamadas "oferta", "nombre de b", "ayudas".
Ahora hay valores ficticios en la Tabla A y la Tabla B como se muestra a continuación.
Tabla A
ayuda aname
1 manzana
2 plátano
3 mango
Tabla B
oferta bname ayudas
1 manzana 1,2
2 plátano 2,1
3 mango 3,1,2
Caso 1: si desea obtener esos registros de la tabla b que tiene 1 valor presente en las columnas de ayudas, debe usar FIND_IN_SET.
Consulta: seleccione * de A JOIN B ON FIND_IN_SET (A.aid, b.aids) donde A.aid = 1;
Caso 2: si desea obtener esos registros de la tabla a que tiene un valor 1 O 2 O 3 presente en las columnas de ayuda, entonces debe usar IN.
Consulta: seleccione * de A JOIN B ON A.aid IN (b.aids);
Ahora aquí, hasta usted, lo que necesita a través de la consulta mysql.
fuente
fuente