2016-03-17 85 views
0

我使用PHP来获取搜索表单的价格和大小标准,并在下面构建MySQL查询。表中的价格字段是一个INT,租赁字段是FLOAT,而大小字段是VARCHAR,因为该值包含度量单位。替换并进行比较

下面的查询使用PHP脚本运行并返回零记录。我直接在桌上运行它,它返回了173条记录。当我直接运行它,我为两者的最小值,千万最高价格,更换PDO的占位符最大规模英尺size_unit0平方英尺对于size_unit1,并且它返回了173条记录。除了零售业外,我无法获得任何条件,但应该有9条记录。

我做了一个var_dump的值代替PHP代码中的size_unit占位符,他们是浮动的。

表格从房地产协会导入数据,这就是为什么size字段是VARCHAR的原因。

我很困惑。

QUERY

SELECT lt.Price, lt.Lease, lt.LeasePerUnit, 
    IF (lt.Price >= :minimum_price AND 
     lt.Price <= :maximum_price, 
     REPLACE(
      FORMAT(lt.Price, 2), ".00", ""), 
      CONCAT(REPLACE(FORMAT(lt.Lease, 2), ".00", ""), "/", lt.LeasePerUnit) 
     ) AS DisplayPrice, 
    IF (lt.Price >= :minimum_price AND 
     lt.Price <= :maximum_price, 
     REPLACE(lt.Price, ".00", ""), REPLACE(lt.Lease, ".00", "") 
     ) AS DisplayPriceSort, 
    lt.ListingId AS MlsNumber, lt.PropertyId, lt.PropertyType, 
    lt.StreetAddress AS Address, lt.City, lt.PublicRemarks, 
    lt.ListAgent1Id, lt.ListAgent2Id 

    FROM listings AS lt 
    WHERE 1 = 1 AND lt.PropertyType = "Retail" 
     AND (
      (lt.Price >= :minimum_price AND lt.Price <= :maximum_price) OR 
      (lt.Lease >= :minimum_price AND lt.Lease <= :maximum_price) 
     ) 
     AND (
      (
       REPLACE(lt.SizeFrontage, ' :size_unit0', '') >= :minimum_size 
       AND REPLACE(lt.SizeFrontage, ' :size_unit0', '') <= :maximum_size 
      ) OR 
      (
       REPLACE(lt.SizeInterior, ' :size_unit0', '') >= :minimum_size 
       AND REPLACE(lt.SizeInterior, ' :size_unit0', '') <= :maximum_size 
      ) OR 
      (
       REPLACE(lt.SizeTotal, ' :size_unit0', '') >= :minimum_size 
       AND REPLACE(lt.SizeTotal, ' :size_unit0', '') <= :maximum_size 
      ) OR 
      (
       REPLACE(lt.SizeFrontage, ' :size_unit1', '') >= :minimum_size 
       AND REPLACE(lt.SizeFrontage, ' :size_unit1', '') <= :maximum_size 
      ) OR 
      (
       REPLACE(lt.SizeInterior, ' :size_unit1', '') >= :minimum_size 
       AND REPLACE(lt.SizeInterior, ' :size_unit1', '') <= :maximum_size 
      ) OR 
      (
       REPLACE(lt.SizeTotal, ' :size_unit1', '') >= :minimum_size 
       AND REPLACE(lt.SizeTotal, ' :size_unit1', '') <= :maximum_size 
      ) 
     ) 

    ORDER BY DisplayPriceSort * 1 DESC 

适用PHP代码生成查询

if (isset($minimum_price) && isset($maximum_price) && !isset($featured_mls_number) && !isset($mls_number)) 
{ 
    if ($transaction_type != '') 
    { 
     if ($transaction_type == 'for_lease') 
     { 
      $where .= ' AND (lt.Lease >= :minimum_price AND lt.Lease <= :maximum_price)'; 
     } 
     elseif ($transaction_type == 'for_sale') 
     { 
      $where .= ' AND (lt.Price >= :minimum_price AND lt.Price <= :maximum_price)'; 
     } 
    } 
    elseif (($transaction_type != '' && $transaction_type == 'for_sale_or_rent') || $transaction_type == '') 
    { 
     $where .= ' AND ((lt.Price >= :minimum_price AND lt.Price <= :maximum_price) OR (lt.Lease >= :minimum_price AND lt.Lease <= :maximum_price))'; 
    } 
    $execute_array[':minimum_price'] = $minimum_price; 
    $execute_array[':maximum_price'] = $maximum_price; 
} 
else 
{ 
    $execute_array[':minimum_price'] = 0; 
    $execute_array[':maximum_price'] = 100000000; 
} 
if (isset($minimum_size) && isset($maximum_size) && !isset($featured_mls_number) && !isset($mls_number)) 
{ 
    #SizeFrontage, SizeInterior, SizeTotal 
    foreach ($size_units_array as $su_key => $su_value) 
    { 
     $size_unit_lower = strtolower($su_key); 
     if ($size_unit_lower == $size_unit) 
     { 
      $where .= " AND ("; 
      for ($i = 0; $i < count($su_value); $i++) 
      { 
       $where .= 
       " 
       (REPLACE(lt.SizeFrontage, CONCAT(' ', :size_unit".$i."), '') >= :minimum_size 
       AND REPLACE(lt.SizeFrontage, CONCAT(' ', :size_unit".$i."), '') <= :maximum_size) 
       OR (REPLACE(lt.SizeInterior, CONCAT(' ', :size_unit".$i."), '') >= :minimum_size 
       AND REPLACE(lt.SizeInterior, CONCAT(' ', :size_unit".$i."), '') <= :maximum_size) 
       OR (REPLACE(lt.SizeTotal, CONCAT(' ', :size_unit".$i."), '') >= :minimum_size 
       AND REPLACE(lt.SizeTotal, CONCAT(' ', :size_unit".$i."), '') <= :maximum_size) 
       "; 
       $execute_array[':size_unit'.$i] = $su_value[$i]; 
       if ($i != count($su_value) - 1) $where .= " OR "; 
      } 
      $where .= ")"; 
     } 
     $execute_array[':minimum_size'] = $minimum_size; 
     $execute_array[':maximum_size'] = $maximum_size; 
    } 
} 

$query = 
' 
    SELECT lt.Price, lt.Lease, lt.LeasePerUnit, 
    IF (lt.Price >= :minimum_price AND lt.Price <= :maximum_price, 
    REPLACE(FORMAT(lt.Price, 2), ".00", ""), CONCAT(REPLACE(FORMAT(lt.Lease, 2), 
    ".00", ""), "/", lt.LeasePerUnit)) AS DisplayPrice, 
    IF (lt.Price >= :minimum_price AND lt.Price <= :maximum_price, 
    REPLACE(lt.Price, ".00", ""), REPLACE(lt.Lease, ".00", "")) AS DisplayPriceSort, 
    lt.ListingId AS MlsNumber, lt.PropertyId, lt.PropertyType, 
    lt.StreetAddress AS Address, lt.City, lt.BedroomsTotal, lt.BathroomTotal, 
    lt.PublicRemarks, lt.ListAgent1Id, lt.ListAgent2Id, 
    ListAgent1OfficeName, ListAgent2OfficeName 
    FROM listings AS lt 
    WHERE '.$where.' 
    ORDER BY '.$sort_by.' 
'; 

回答

1

我很惊讶你没有看到错误消息

警告:PDOStatement对象::执行() :SQLSTATE [HY093]:无效的参数编号:绑定变量的数量与令牌的数量不匹配

PDO不会将变量绑定到您的:size_unitN参数,因为它们位于SQL查询中的单引号内。这意味着它们被视为字符串“:size_unitN”。

REPLACE(lt.SizeFrontage, CONCAT(' ', :size_unit0), '') >= :minimum_size 

如果大小的数据始终是:

相反,你应该带引号的字符串和前插的空间外的参数将它们移动使用CONCAT,例如

REPLACE(lt.SizeFrontage, ' :size_unit0', '') >= :minimum_size 

应改为格式是一个整数,后跟一个空格,后跟一个字母单位,根本没有必要使用REPLACE函数。如果你明确地将你的minimum_size和maximum_size作为整数绑定,MySQL也会将这些列转换为整数以进行比较。例如

$q = $pdo->prepare(
    "SELECT * FROM listings WHERE SizeFrontage > :min AND SizeFrontage < :max"); 
$q->bindValue(":min", 10, PDO::PARAM_INT); 
$q->bindValue(":max", 35, PDO::PARAM_INT); 

您应该考虑改进数据模型。目前你的查询效率很低。如果将大小作为整数存储在数据库中,那么搜索速度会更快,尤其是您可以对字段进行索引。如果您有大量记录,这可能是一个特别的问题。

如果记录存储在使用不同单位的数据库(例如一些平方米,一些平方英尺),你将只能使用REPLACE语法在任何一个时间,以寻找其中的一些,你会使用PDO::PARAM_INT获得不正确的结果。更好的方法是将所有尺寸转换为一个单元,然后将它们保存到数据库中,然后根据需要将用户的请求转换为同一单元。

+0

谢谢马特。不幸的是,仍然无法正常工作。现在通过PHP 1记录并通过表格直接记录173条记录。建议您替换所有大小字段/ PDO占位符的REPLACE MySQL代码。 – spiderling

+0

你能提供你用来绑定参数和获取结果的代码吗? –

+0

用它更新了原来的帖子。 – spiderling