Eu tenho 2 tabelas no meu banco de dados. Um é para pedidos, e um é para empresas.
Orders tem esta estrutura:
E a empresa tem essa estrutura:
Para obter os nomes das empresas de um pedido, posso fazer uma consulta como:
Essa consulta funciona bem, mas a consulta a seguir não.
Por que a primeira consulta funciona, mas não a segunda?
A primeira consulta retorna:
A segunda consulta retorna apenas:
Por que isso ocorre, por que a primeira consulta retorna todas as empresas, mas a segunda consulta retorna apenas a primeira?
attachedCompanyIDs é uma grande string, então o MySQL tentar encontrar empresa neste seu elenco para inteiro
Acho que este é o melhor exemplo mysqltutorial.org/mysql-find_in_set
attachedCompanyIDsé um valor escalar que é convertido em INT(tipo de companyID).
O elenco retorna apenas números até o primeiro não dígito (uma vírgula no seu caso).
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, MySQLpois o último não suporta matrizes.
Você pode achar este artigo interessante (consulte #2):
10 coisas no MySQL (que não funcionarão como o esperado)
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:
Obrigada pelo esclarecimento. Não percebi que o campo attachedCompanyIDs foi convertido para um INT. Existe alguma maneira de contornar isso no MySQL? FIND_IN_SETfunciona, mas não usa índices e pode ser lento com muitas informações na tabela Empresa.
Você pode explicar essa atualização? O que exatamente isso faz, porque parece funcionar.
@Rocket: retira positens do início do CVSe lança o restante em número inteiro.
— Quassnoi 11/11/2010
Polegares para cima (y) para10 things in MySQL (that won't work as expected)
— NullPointer 28/02
@Quassnoi, por que você escreve CROSS JOIN? Eles não são todos iguais no MySQL?
— Pacerier 18/04/2015
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
Para obter o nome de todas as empresas relacionadas, não com base em um ID específico.
— Anupriya Pundir
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)
— superfro
Há mais linhas nas duas tabelas do que estou mostrando. Nas duas tabelas, existe o ID do usuário no qual você está conectado, entrando nessa ajuda?
Bem, você só precisa alterar qualquer coisa se sua primeira consulta não retornar os resultados esperados. Se a primeira consulta estiver retornando os resultados desejados, não haverá realmente nenhum problema. Eu pensei que você estava curioso para saber por que os 2 não mostram o mesmo resultado.
@ superfro, estou curioso para saber por que os 2 não mostram o mesmo resultado.
sua segunda consulta está usando um where IN (values), onde a parte 'values' vem da tabela e é uma string. A cadeia está sendo avaliada como um valor booleano, que = 1 e é por isso que mostra apenas a primeira linha.
Se você está preocupado com o desempenho, provavelmente deve pensar em alterar sua estrutura de banco de dados. Você pode adicionar uma tabela conjunta que contém 2 valores, order_ID e company_ID, em vez de usar a lista delimitada por vírgulas na tabela de pedidos. Isso permitiria que você selecionasse o nome da empresa que ingressou à esquerda em order_companies em company.company_ID = order_companies.company_ID deixou em pedidos de ingresso em order_companies.order_ID = order.order_ID em que orders.order_ID = 1; Isso usaria índices.
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.
lances de bname
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.
Esta questão já foi resolvida. Também não acho que seu segundo exemplo, com IN, funcione ... esse foi basicamente o problema que eu estava tentando resolver no começo.
Bem-vindo ao SO! Código sem explicações raramente é útil. Nesse caso, ele nem tenta responder à pergunta "Por que ...?". Observe também que esta pergunta em particular já possui uma resposta aceita, que fornece uma resposta bem recebida (> 80 votos!). Como novo usuário, talvez seja melhor se concentrar em perguntas não respondidas e / ou fazer boas perguntas.