简体   繁体   中英

MySQL/PHP - Filter on numeric values on fields that are not numeric

Basically, the idea is that people filter search results on the length. However, length is stored in a text field, as this can be different from item to item. An item could be 16,20 metres, and another could be 8.1m.

How would one even start? Get all the possible values from the database, change them to the format that is filtered on (parse everything to numeric only, comma separated?), get the associated ID, and then only show all the info related to those IDs, or is there a way I haven't found yet?

Kind regards.

edit: Standardizing format is a solution, but not one I can apply in this situation. I am not allowed to do this. It gets worse - the filtering can have both a minimum and a maximum value. Minimum: 4 and maximum: 8 should show everything between those lengths. 6.1m, 7,82 metres, 5.

Because I couldn't change the way the database was set up (standardize is, keep separate fields for the length itself, a float/double, and a field for the appendix), I've decided to go with this approach.

First get all the possible lengths, then:

foreach($lengths as $length) {
 $cLengths[$length['item_id']] = preg_replace("/[^0-9,.]/", "", str_replace(',', '.', $length['field_value']));
}

Assuming the page would then be called with &minLength=2&maxLength=10 in the URL:

$minLength = $_GET['minLength'];
$maxLength = $_GET['maxLength'];
if(!is_null($minLength) && !is_null($maxLength)) {
 $filteredItems = '';
 foreach($cLengths as $itemId => $cL) {
  if($cL >= $minLength && $cL <= $maxLength) {
   $filteredItems .= $itemId . ',';
  }
 }
 $filteredItems = substr($filteredItems, 0, -1);
 $where .= 'item_id IN(' . $filteredItems . ') AND ';
}

I would recommend to standardize a format for length. It is hard to filter numeric values stored in different formats.

You can use the LIKE operator to search for any pattern in a string:

SELECT * FROM table WHERE length LIKE '%filtervalue%'

I would simply enforce standard during your query. Assuming your length column is named "length" and you query table is "table":

SELECT something, replace(length,',','.') + 0 as mylen FROM `table` HAVING mylen BETWEEN 16.2 AND 18

It would not be very fast, you can also use replace + 0 directly in where, it would remove the need for HAVING that is:

SELECT something FROM `table` replace(length,',','.') + 0 BETWEEN 16.2 AND 18

Good Luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM