FIND_IN_SET() vs EN()
J'ai 2 tables dans ma base de données. L'un est pour les commandes, et un pour les entreprises.
Commandes a cette structure:
OrderID | attachedCompanyIDs
------------------------------------
1 1,2,3
2 2,4
Et de l'Entreprise a cette structure:
CompanyID | name
--------------------------------------
1 Company 1
2 Another Company
3 StackOverflow
4 Nothing
Pour obtenir une ordonnance les entreprises des noms, je peux faire une requête en tant que tel:
SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)
Que la requête fonctionne très bien, mais la requête suivante ne fonctionne pas.
SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)
Pourquoi la première requête travail, mais pas la seconde?
La première requête retourne:
name
---------------
Company 1
Another Company
StackOverflow
La deuxième requête ne retourne:
name
---------------
Company 1
Pourquoi est-ce, pourquoi la première requête en retour toutes les entreprises, mais la deuxième requête ne retourne que le premier?
- attachedCompanyIDs est une grande chaîne, de sorte que mysql essayer de trouver de l'entreprise dans ce son cast en entier
- Je pense que c'est le meilleur exemple mysqltutorial.org/mysql-find_in_set
Vous devez vous connecter pour publier un commentaire.
attachedCompanyIDs
est une valeur scalaire qui est remis enINT
(type decompanyID
).Le casting ne retourne que des nombres jusqu'à la première non-chiffres (une virgule dans votre cas).
Ainsi,
Dans
PostgreSQL
, vous pourriez lancer la chaîne en un tableau (ou les stocker dans un tableau en premier lieu):et ce serait même l'utilisation d'un index sur
companyID
.Malheureusement, cela ne fonctionne pas dans
MySQL
puisque ce dernier ne prend pas en charge les tableaux.Vous pouvez trouver cet article intéressant (voir
#2
):Mise à jour:
Si il ya une limite raisonnable sur le nombre de valeurs dans des listes séparées par des virgules (par exemple, pas plus de
5
), de sorte que vous pouvez essayer d'utiliser cette requête:FIND_IN_SET
fonctionne, mais n'est pas utilise les index, et peut être lente, avec beaucoup d'infos dans la table de la Société.pos
les éléments depuis le début de laCVS
et jette le reste en entier.10 things in MySQL (that won’t work as expected)
CROSS JOIN
? Ne sont-ils pas tout de même dans MySQL?attachedCompanyIDs est une grande chaîne, de sorte que mysql essayer de trouver de l'entreprise dans ce son cast en entier
lorsque vous utilisez lorsque, dans
donc si comapnyid = 1 :
c'est return true
mais si le nombre 1 n'est pas en premier lieu
ses return false
De la totalité des sociétés liées nom, pas de base de votre Id.
parce que la seconde requête est à la recherche pour les lignes avec l'id est 1 OU 2 OU 3,
la première requête est à la recherche pour l'un des délimité par des virgules, les valeurs d'exister dans companyID,
et un autre problème ici c'est que vous n'êtes pas joindre les tables sur une clé commune dans votre où vous allez obtenir une mutation de lignes = count(table1) * count(table2);
Votre problème existe vraiment avec la partie 2 de ma réponse. (avec votre deuxième question)
SELECT name FROM company WHERE companyID IN (1,2,3)
œuvres.Laissez-moi vous expliquer quand utiliser FIND_IN_SET et Quand les utiliser DANS.
Prenons Une table qui a des colonnes nommées "aide","nom".
Prenons la table B qui a des colonnes nommées "offre","nom","sida".
Maintenant il y a des valeurs factices dans le Tableau A et B comme ci-dessous.
Table Un
aide anom
1 Pomme
2 Bananes
3 Mangue
Tableau B
offre anom sida
1 Pomme 1,2
2 Bananes 2,1
3 Mangue 3,1,2
Décision1: si vous voulez obtenir les enregistrements de la table b qui a valeur de 1 présents dans sida colonnes, alors vous devez utiliser FIND_IN_SET.
Requête: select * from UNE JOINTURE B SUR FIND_IN_SET(A. de l'aide,b.sida) où A. aid = 1 ;
Case2: si vous voulez obtenir les enregistrements de la table de la qui a 1 ou 2 OU 3, la valeur actuelle à l'aide de colonnes, il faut utiliser DANS les.
Requête: select * from UNE JOINTURE B SUR A. de l'aide DANS b.sida);
Maintenant ici jusqu'à vous que ce que vous avez besoin par le biais de requête mysql.