8
votes

Valeurs distinctes floues

J'ai une base de données de listes immobilières et j'ai besoin de renvoyer une liste de quartiers. En ce moment, j'utilise MySQL distinct qui retourne toutes les valeurs distinctes. Mon probelm est qu'il y a beaucoup de quartiers ayant des noms similaires: Exemple:

Park View Sub 1
Park View
Park View Sub 2
Park View Sub 3
Great Lake Sub 1
Great Lake Sub 2
Great Lake 
Great Lake Sub 3


7 commentaires

Pourriez-vous ajouter la sortie nécessaire à votre question pour une meilleure compréhension ?.?


Est "Sub X" la seule chaîne qui sera à la fin, ou est cette variable de texte?


@sshekhar: " retourner" Vue Park "et" Great Lake ". " - C'est la sortie attendue.


Merci Travesy3. En ce qui concerne Sub X - non. C'est juste exemple. Cela pourrait être tout comme SUB, FLG, UNITÉ, BLDG, etc.


@ user982853 Comment saurez-vous ce qui est et n'est pas le texte de chaîne pertinent, alors? Retraité, comment la solution doit-elle déterminer quelle partie du texte est importante et quelle partie n'est pas? Existe-t-il une liste absolue de texte "addon"? Y a-t-il une limite de caractère? Je ne comprends tout simplement pas comment votre code devrait déterminer que dans "Sub" Park View Sub "," Sub "n'est pas pertinent, mais dans" Sub Yellow "," SUB "devrait rester en place.


@Chris: +1 pour utiliser "Sub jaune" à titre d'exemple. Votre point est également très pertinent, mais le +1 est particulièrement pour la référence des Beatles.


@ user982853: cela peut être accompli dans MySQL. Je m'attends à ce que vous souhaitiez utiliser les valeurs que vous revenez à être utilisées dans un prédicat (où la clause) d'une requête ultérieure. Voir ma réponse; Je serais heureux de fournir une explication de la manière dont cela fonctionne.


4 Réponses :


0
votes

Si vous avez toujours une entrée sans la partie «SUB # '», vous pouvez faire quelque chose comme ceci: XXX PRE>

Pour trier par la longueur de la chaîne: P>

SELECT DISTINCT neighborhood FROM table ORDER BY LENGTH(neighborhood);


1 commentaires

La seule chose qui ne va pas, à l'exclusion de SUB, c'est que, dans l'événement "View View Sub 1", est le seul quartier, je veux qu'il retourne celui-là. La seule fois où je veux qu'ils excluent, c'est s'il y a déjà un quartier le contenant.



0
votes

Vous pouvez utiliser PHP's similaire_text pour obtenir une solution simple mise en œuvre. Si vous pré-triez vos données de manière à ce que les adresses plus courtes, souhaitées, elles devraient d'abord fonctionner. De plus, si des adresses "différentes" ne sont pas trop similaires, cela fonctionnera mieux (mais vous pouvez toujours suivre le seuil): xxx

pour d'autres alternatives, vous pouvez également consulter PHP Levenshtein et Soundex , ainsi que MySQL's Soundex () .

Un autre, pseudo-flou La méthode consiste à faire trier les adresses alphabétiquement (via MySQL ou PHP) et la boucle en une seule par une; Si l'adresse actuelle commence - avec le texte d'une adresse unique déjà trouvée, déposez-le. Cela fonctionne de la même manière que l'utilisation d'une méthode floue réelle, mais elle est plus droite à la pointe: xxx

Cette méthode ne fonctionnera que si elles sont triées, comme le Adresse plus courte Park View Il faudrait être trouvé avant Park View Sub 1 . Si vos adresses sont trop similaires les unes aux autres et ci-dessus similaire_text La méthode tombe une trop nombreuses, vous pouvez essayer cette dernière fonction car elle est plus stricte.


0 commentaires

2
votes

Voici certaines choses que vous pouvez essayer; Vraisemblablement, vous recherchez des correspondances exactes et des allumettes fermées.

Première recherche d'une correspondance exacte. Ensuite, recherchez un match similaire sur le nom inversé. Cherchez ensuite le match avec les moins de caractères supplémentaires.

Voici une requête qui fera tout cela. Notez que vous devrez stocker le nom de lieu inversé dans une colonne indexée si vous voulez que cela soit efficace. xxx

remarque comment cette requête syndicale utilise ordinal Pour comprendre la meilleure correspondance.

Vérifiez ici ici: http://sqlfiddle.com/#!2/76A97/9/0


1 commentaires

Il ne renvoie que Park View Bt, il devrait renvoyer le lac vert aussi comme c'est aussi une valeur distincte.



0
votes

L'exemple de requête ci-dessous vous procurera le jeu de résultats spécifié à l'aide de MySQL, mais cela ne fait pas vraiment "correspondance floue", au moins, ce n'est pas comment je décrirais l'algorithme. (Ceci implémente l'algorithme que vous décrivez - triez par des valeurs, puis en vérifiant chaque valeur pour voir si la partie principale "correspond à" une valeur extraite précédemment.)

Ceci trouve une "correspondance exacte" du leader partie de la valeur de voisinage par rapport à la valeur des rangées extraites précédemment, il n'y a pas vraiment de "flou" sur la correspondance. P>

Lorsque la requête rencontre une valeur "inégalée", elle marque cette valeur. est "inégalé". Pour la valeur suivante récupérée, il vérifie si cette valeur commence par la valeur précédemment "inégalée"; Si la partie principale de la chaîne est une correspondance exacte, la valeur est supprimée. Sinon, la valeur est marquée comme une valeur "inégalée" et est conservée. P>

Cette approche utilise des vues en ligne (ou des "tables dérivées" comme le fait référence à MySQL). La vue en ligne la plus interne (aliased selon s) nous reçoit une liste triée de valeurs distinctes pour le quartier. Le "truc" (si vous voulez appeler cela) est dans la prochaine vue en ligne (aliasé comme "T") où nous utilisons des variables utilisateur MySQL pour faire référence à une valeur précédemment extraite. P>

à éviter Toute question avec des "caractères spéciaux", nous faisons une comparaison sur l'égalité sur les caractères principaux. P>

Voici toute la requête: P>

SELECT t.*
  FROM mytable t
 WHERE t.neighborhood LIKE CONCAT('Great Lake','%')

SELECT t.*
  FROM mytable t
 WHERE t.neighborhood REGEXP CONCAT('^','Great Lake')


0 commentaires