2010-07-16 5 views
0

J'ai une chaîne qui est définie comme un ou plusieurs entiers séparés par des points tels que, 543.21, 12345 109.87.654, etc. Je suis stocker des valeurs dans une base de données MySQL et doivent trouver les lignes qui se comparent avec une valeur fournie. Ce que je veux, c'est sélectionner des lignes en comparant chaque composant de la chaîne au composant correspondant de la chaîne d'entrée. Avec comparaison de chaînes standard dans MySQL, voici où cela se décompose:ActiveRecord/MySQL Sélectionner l'état des composants Comparer cordes

mysql> SELECT '543.21' >= '500.21' 
-> 1 
mysql> SELECT '543.21' >= '5000.21' 
-> 1 

Ceci est naturel, car la comparaison de chaînes est une comparaison « dictionnaire » qui ne tient pas compte de la longueur de chaîne, mais je veux un 0 résultat sur la deuxième requête.

est-il un moyen de fournir une allusion à MySQL sur la façon de les comparer? Sinon, y a-t-il un moyen d'indiquer à ActiveRecord comment faire cela pour moi? À l'heure actuelle, la meilleure solution que j'ai trouvée est de sélectionner toutes les lignes et de filtrer les résultats en utilisant les méthodes split et reject de Ruby. (L'ensemble des données est très faible et ne risquent pas de se développer terriblement bien dans un avenir prévisible, il est donc une option raisonnable, mais s'il y a un moyen plus simple, je ne suis pas vu que je serais heureux de le savoir.)

+0

Avez-vous besoin de ces points? – klew

Répondre

0

Vous pouvez utiliser REPLACE pour supprimer des points et CAST pour convertir la chaîne en entier:

SELECT CAST(REPLACE("543.21", ".", "") AS SIGNED) >= CAST(REPLACE("5000.21", ".", "") AS SIGNED) 
+0

Je ne pense pas que ça marchera non plus, mais c'est une bonne idée. Voici où je pense que cela se décomposerait. '543.21.9> 543.2.19' doit être vrai, mais en utilisant votre méthode, il sera égal. – jxpx777

+0

J'accepte celui-ci parce que je pense que c'est la chose la plus proche de la réponse. Nous avons fini par prendre une direction légèrement différente, mais c'est un bon début. – jxpx777

0
mysql> SELECT '543.21' >= '5000.21'; 
+-----------------------+ 
| '543.21' >= '5000.21' | 
+-----------------------+ 
|      1 | 
+-----------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT '543.21'+0 >= '5000.21'+0; 
+---------------------------+ 
| '543.21'+0 >= '5000.21'+0 | 
+---------------------------+ 
|       0 | 
+---------------------------+ 
1 row in set (0.00 sec) 

Cela ne fonctionne en effet que pour les flottants valides. Le faire pour plus de 1 point demanderait beaucoup de comparer des SUBSTRING_INDEX(SUBSTRING_INDEX(field, '.', <positionnumber you're comparing>), '.', -1) (avec une répétition manuelle pour le nombre maximum de position de vous comparez)

+0

Cela fonctionne quand il y a seulement deux composants, mais s'il y en a trois ou plus, il casse: mysql> SELECT '543.21.5' + 0> = '543.21.5' + 0; + ------------------------------ + | '543.21.5' + 0> = '543.21.5' + 0 | + ------------------------------ + | 1 | + ------------------------------ + 1 rang dans le jeu, 2 avertissements (0.00 sec) – jxpx777

+0

Mon mauvais, didn pas lu la question tout bien, supposé flotteurs valides. – Wrikken