Maison >base de données >tutoriel mysql >FIND_IN_SET() vs IN() : pourquoi l'un renvoie-t-il tous les résultats alors que l'autre ne renvoie que le premier ?

FIND_IN_SET() vs IN() : pourquoi l'un renvoie-t-il tous les résultats alors que l'autre ne renvoie que le premier ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-11 20:46:13936parcourir

FIND_IN_SET() vs. IN(): Why Does One Return All Results While the Other Only Returns the First?

FIND_IN_SET() vs IN() : Comprendre l'écart dans les résultats des requêtes

Lors de l'interrogation de bases de données relationnelles, il est nécessaire de comprendre la distinction entre les fonctions FIND_IN_SET() et IN(). Cet article examine leur comportement dans un scénario de base de données spécifique.

Problème :

Considérez deux tableaux : les commandes et l'entreprise. La table des commandes comprend une colonne attachmentCompanyIDs qui contient une liste d'ID d'entreprise séparés par des virgules. La table des sociétés contient les noms réels des sociétés. Lors de l'exécution d'une requête pour récupérer les noms de sociétés associés à une commande à l'aide de la fonction FIND_IN_SET(), elle renvoie tous les résultats attendus. Cependant, remplacer FIND_IN_SET() par IN() dans la requête renvoie uniquement le premier nom de la société.

Cause :

La fonction IN() interprète les attachmentCompanyIDs comme un seul entier, alors que FIND_IN_SET() le traite comme une chaîne. Lorsque attachmentCompanyIDs est converti en nombre entier, il conserve uniquement les chiffres jusqu'au premier caractère non numérique (la virgule). Par conséquent, la requête IN() renvoie uniquement l'entreprise associée au premier numéro de la liste séparée par des virgules.

Solution :

Pour contourner ce problème, PostgreSQL propose une solution plus robuste :

SELECT name
FROM orders
JOIN company
ON companyID = ANY(('{' || attachedCompanyIDs || '}')::INT[])
WHERE orderID = 1;

Cette requête exploite la fonction ANY() pour convertir les attachmentCompanyIDs sous forme de tableau, permettant une utilisation efficace d'un index sur companyID.

Mise à jour :

Pour les bases de données MySQL, qui ne prennent pas en charge les tableaux, une approche alternative peut être utilisée :

SELECT name
FROM orders
CROSS JOIN
(
    SELECT 1 AS pos
    UNION ALL
    SELECT 2 AS pos
    UNION ALL
    SELECT 3 AS pos
    UNION ALL
    SELECT 4 AS pos
    UNION ALL
    SELECT 5 AS pos
) q
JOIN company
ON companyID = CAST(NULLIF(SUBSTRING_INDEX(attachedCompanyIDs, ',', -pos), SUBSTRING_INDEX(attachedCompanyIDs, ',', 1 - pos)) AS UNSIGNED);

Cette requête parcourt les positions potentielles, extrayant les sous-chaînes des attachmentCompanyID pour correspondre à l'ID de l'entreprise. Cela implique plusieurs jointures, mais cela reste fonctionnel pour les scénarios avec un nombre limité d'identifiants d'entreprise dans la liste séparée par des virgules.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn