Eu tenho 2 tabelas no meu banco de dados. Um é para pedidos, e um é para empresas.
Orders tem esta estrutura:
OrderID | attachedCompanyIDs
------------------------------------
1 1,2,3
2 2,4
E a empresa tem essa estrutura:
CompanyID | name
--------------------------------------
1 Company 1
2 Another Company
3 StackOverflow
4 Nothing
Para obter os nomes das empresas de um pedido, posso fazer uma consulta como:
SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)
Essa consulta funciona bem, mas a consulta a seguir não.
SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)
Por que a primeira consulta funciona, mas não a segunda?
A primeira consulta retorna:
name
---------------
Company 1
Another Company
StackOverflow
A segunda consulta retorna apenas:
name
---------------
Company 1
Por que isso ocorre, por que a primeira consulta retorna todas as empresas, mas a segunda consulta retorna apenas a primeira?
Respostas:
attachedCompanyIDs
é um valor escalar que é convertido emINT
(tipo decompanyID
).O elenco retorna apenas números até o primeiro não dígito (uma vírgula no seu caso).
Portanto,
Em
PostgreSQL
, você pode converter a string na matriz (ou armazená-la como uma matriz em primeiro lugar):e isso usaria mesmo um índice
companyID
.Infelizmente, isso não funciona,
MySQL
pois o último não suporta matrizes.Você pode achar este artigo interessante (consulte
#2
):Atualizar:
Se houver algum limite razoável no número de valores nas listas separadas por vírgula (digamos, não mais que
5
), você poderá tentar usar esta consulta:fonte
FIND_IN_SET
funciona, mas não usa índices e pode ser lento com muitas informações na tabela Empresa.pos
itens do início doCVS
e lança o restante em número inteiro.10 things in MySQL (that won’t work as expected)
CROSS JOIN
? Eles não são todos iguais no MySQL?attachedCompanyIDs é uma string grande, então o mysql tenta encontrar a empresa neste seu elenco para inteiro
quando você usa onde
então se comapnyid = 1:
isso é retorno verdadeiro
mas se o número 1 não estiver em primeiro lugar
seu retorno falso
fonte
Para obter o nome de todas as empresas relacionadas, não com base em um ID específico.
fonte
como a segunda consulta procura linhas com o ID 1 OU 2 OU 3, a primeira consulta procura um dos valores delimitados por vírgula no ID da empresa,
e outro problema aqui é que você não está juntando as tabelas em uma chave comum no seu local, para obter uma mutação de linhas que = count (tabela1) * contagem (tabela2);
Seu problema realmente existe com a parte 2 da minha resposta. (com sua segunda consulta)
fonte
Deixe-me explicar quando usar FIND_IN_SET e quando usar IN.
Vamos pegar a tabela A que possui colunas denominadas "aid", "aname". Vamos pegar a tabela B, que possui colunas denominadas "bid", "bname", "aids".
Agora, existem valores simulados na Tabela A e na Tabela B, como abaixo.
Quadro A
aid aname
1 Apple
2 Banana
3 Manga
Quadro B
lances de bname
1 Apple 1,2
2 Banana 2,1
3 Manga 3,1,2
Caso1: se você deseja obter esses registros da tabela b que possui 1 valor presente nas colunas de aids, use FIND_IN_SET.
Consulta: selecione * em A JOIN B ON FIND_IN_SET (A.aid, b.aids) em que A.aid = 1;
Caso2: se você deseja obter esses registros da tabela a com o valor 1 OU 2 OU 3 presente nas colunas de ajuda, é necessário usar IN.
Consulta: selecione * em A JOIN B ON A.aid IN (b.aids);
Agora, aqui você decide o que precisa através da consulta mysql.
fonte
fonte