J'ai 2 tables dans ma base de données. L'un concerne les commandes et l'autre les entreprises.
Les commandes ont cette structure:
OrderID | attachedCompanyIDs
------------------------------------
1 1,2,3
2 2,4
Et la société a cette structure:
CompanyID | name
--------------------------------------
1 Company 1
2 Another Company
3 StackOverflow
4 Nothing
Pour obtenir les noms des sociétés d'une commande, je peux faire une requête en tant que telle:
SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)
Cette requête fonctionne correctement, mais pas la requête suivante.
SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)
Pourquoi la première requête fonctionne-t-elle mais pas la seconde?
La première requête renvoie:
name
---------------
Company 1
Another Company
StackOverflow
La deuxième requête ne renvoie que:
name
---------------
Company 1
Pourquoi est-ce, pourquoi la première requête renvoie toutes les sociétés, mais la deuxième requête ne renvoie que la première?
Réponses:
attachedCompanyIDs
est une valeur scalaire qui est convertie enINT
(type decompanyID
).La distribution ne renvoie que les nombres jusqu'au premier non-chiffre (une virgule dans votre cas).
Donc,
Dans
PostgreSQL
, vous pouvez convertir la chaîne en tableau (ou la stocker en tant que tableau en premier lieu):et cela utiliserait même un index sur
companyID
.Malheureusement, cela ne fonctionne pas
MySQL
car ce dernier ne prend pas en charge les tableaux.Vous pouvez trouver cet article intéressant (voir
#2
):Mettre à jour:
S'il y a une limite raisonnable sur le nombre de valeurs dans les listes séparées par des virgules (par exemple, pas plus de
5
), vous pouvez donc essayer d'utiliser cette requête:la source
FIND_IN_SET
fonctionne, mais n'utilise pas d'index et peut être lent avec beaucoup d'informations dans la table Company.pos
éléments depuis le début deCVS
et transforme le reste en entier.10 things in MySQL (that won’t work as expected)
CROSS JOIN
? Ne sont-ils pas tous identiques dans MySQL?AttachCompanyIDs est une grande chaîne, donc mysql essaie de trouver une société dans son cast en entier
lorsque vous utilisez où dans
donc si comapnyid = 1:
c'est le retour vrai
mais si le chiffre 1 n'est pas en premier lieu
son retour faux
la source
Pour obtenir le nom de toutes les sociétés associées, non basé sur un identifiant particulier.
la source
parce que la deuxième requête recherche des lignes avec l'ID 1 OU 2 OU 3, la première requête recherche l'une des valeurs délimitées par des virgules dans companyID,
et un autre problème ici est que vous ne joignez pas les tables sur une clé commune dans votre où vous allez donc obtenir une mutation de lignes qui = count (table1) * count (table2);
Votre problème existe vraiment avec la partie 2 de ma réponse. (avec votre deuxième requête)
la source
Laissez-moi vous expliquer quand utiliser FIND_IN_SET et quand utiliser IN.
Prenons la table A qui a des colonnes nommées "aid", "aname". Prenons le tableau B qui a des colonnes nommées "bid", "bname", "aids".
Maintenant, il y a des valeurs fictives dans les tableaux A et B comme ci-dessous.
Tableau A
aide aname
1 pomme
2 banane
3 mangue
Tableau B
enchérir bname aids
1 pomme 1,2
2 Banane 2,1
3 Mangue 3,1,2
Cas 1: si vous voulez obtenir ces enregistrements de la table b qui a 1 valeur présente dans les colonnes des aides, vous devez utiliser FIND_IN_SET.
Requête: sélectionnez * dans A JOIN B ON FIND_IN_SET (A.aid, b.aids) où A.aid = 1;
Cas 2: si vous voulez obtenir ces enregistrements de la table a qui a 1 OU 2 OU 3 valeur présente dans les colonnes d'aide, vous devez utiliser IN.
Requête: sélectionnez * dans A JOIN B ON A.aid IN (b.aids);
Maintenant, voici ce dont vous avez besoin via une requête mysql.
la source
la source