【问题标题】:MySQL/PHP - Filter on numeric values on fields that are not numericMySQL/PHP - 过滤非数字字段上的数值
【发布时间】:2014-01-23 15:33:57
【问题描述】:

基本上,这个想法是人们根据长度过滤搜索结果。但是,长度存储在文本字段中,因为这可能因项目而异。一个项目可能是 16.20 米,另一个可能是 8.1m。

如何开始?从数据库中获取所有可能的值,将它们更改为过滤的格式(仅将所有内容解析为数字,逗号分隔?),获取关联的 ID,然后仅显示与这些 ID 相关的所有信息,或者是否存在一种我还没有找到的方法?

亲切的问候。

编辑:标准化格式是一种解决方案,但我不能在这种情况下应用。我不允许这样做。情况变得更糟 - 过滤可以同时具有最小值和最大值。最小值:4 和最大值:8 应该显示这些长度之间的所有内容。 6.1m,7.82 米,5.

【问题讨论】:

  • 您应该规范化数据,这意味着可能将值和测量单位分成两个字段。
  • 我真的应该,而且我真的希望我可以。然而,这是别人的项目,我不能也不允许改变它,很遗憾。
  • 您不必更改核心表,但您可以创建一个正确执行此操作的镜像表,然后在镜像表上进行搜索。可以每小时/每天从头开始重新创建镜像表(取决于大小和更新频率),或者,如果您在损坏的表中有 updated_at 列,则可以使其几乎每 10 分钟同步一次。

标签: php mysql filter filtering


【解决方案1】:

我建议对长度格式进行标准化。很难过滤以不同格式存储的数值。

您可以使用 LIKE 运算符搜索字符串中的任何模式:

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

【讨论】:

  • 情况变得更糟了。它必须同时具有最小值和最大值。其中一个可以为空,两个都可以为空,都可以初始化。
  • 当然你必须规范化格式。您需要编写一个可以执行此操作的函数(根据所有可能的值解析输入并返回标准化(浮点)值)。更好的是在将值保存到数据库并存储值标准化之前使用此功能(您可以将新列添加到表中,以防您还需要原始值)。您可以使用 SQL 轻松过滤值。如果无法修改数据库,则必须选择所有行并在 PHP 中对其进行过滤(使用与以前相同的函数)但这会导致性能问题。
  • 正如我在编辑中解释的以及对另一个答案的回应——我希望我能,但我不能。那是不可能的。相信我,这是我跳到的第一件事,但我做不到。
【解决方案2】:

因为我无法更改数据库的设置方式(标准化是,为长度本身保留单独的字段、float/double 和附录的字段),我决定采用这种方法.

先得到所有可能的长度,然后:

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

假设页面会在 URL 中使用 &minLength=2&maxLength=10 调用:

$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 ';
}

【讨论】:

    【解决方案3】:

    我只会在您的查询期间强制执行标准。假设您的长度列被命名为“长度”并且您查询的表是“表”:

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

    不会很快,你也可以直接在where中使用replace + 0,这样就不需要HAVING了:

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

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      • 2017-09-03
      • 2020-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多