使用`BETWEEN 0和100000`时,Wordpress不会选择行

时间:2016-10-19 14:37:03

标签: php mysql wordpress

我有一个Wordpress安装,列出待售物业。我正在尝试在2个值之间找到属性。

我遇到的问题是我做的事情:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )  INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id )  INNER JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id )  INNER JOIN wp_postmeta AS mt3 ON ( wp_posts.ID = mt3.post_id ) WHERE 1=1  AND ( 
  ( wp_postmeta.meta_key = 'type_of_property' AND wp_postmeta.meta_value IN ('semidetached') ) 
  AND 
  ( mt1.meta_key = 'property_value' AND mt1.meta_value BETWEEN '0' AND '100000' )
) AND wp_posts.post_type = 'shared_ownership' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC

它只返回3行。但是,如果我将其更改为以下内容:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )  INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id )  INNER JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id )  INNER JOIN wp_postmeta AS mt3 ON ( wp_posts.ID = mt3.post_id ) WHERE 1=1  AND ( 
  ( wp_postmeta.meta_key = 'type_of_property' AND wp_postmeta.meta_value IN ('semidetached') ) 
  AND 
  ( mt1.meta_key = 'property_value' AND mt1.meta_value BETWEEN '0' AND '99999' )
) AND wp_posts.post_type = 'shared_ownership' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC

按预期返回13行。这里唯一的区别是最大数量,我不太明白为什么99999100000在数据库结果方面存在巨大差异。

wordpress是否只是忽略了额外的零?它不是一个数字吗?我不确定如何解决这个问题。

修改

以下是我如何使用高级自定义字段等构建此查询的示例。

$args = array(
        'post_type' => $propertyType[0],
        'paged'=>$paged,
        'meta_query' => array(
            'relation' => 'AND',
            array(
                'key' => 'type_of_property',
                'value' => $data[0],
            ),
            array(
                'key' => $propertyValue,
                'value' => array($data[3], $data[4]),
                'compare' => 'BETWEEN'
            ),
            array(
                'key' => 'number_of_bedrooms',
                'value' => $data[2],
                'compare' => 'IN'
            ),
            array(
                'key' => 'town_index',
                'value' => $data[1],
                'compare' => 'IN'
            ),
        )
    );
}
$loop = new WP_Query( $args );

$data是一个数组。 $data[3]$data[4]等于我上面提到的值,只是从表单POST中填充。

3 个答案:

答案 0 :(得分:2)

尝试删除单引号。我相信SQL不确定如何"键入"那些值进行比较。 (字符串与标量,@danfromgermany在评论中指出。)

测试你的额外零"假设,这将证明这一点:尝试将10000值更改为100001。正如您所怀疑的那样,如果没有右边填充的0,SQL可能会更好地解释查询。

修改:要对您的查询进行精细控制以避免WP应用单引号,您可以使用$wpdb对象。

来自https://codex.wordpress.org/Class_Reference/wpdb

  

使用$ wpdb对象

     

WordPress提供了一个全局对象变量$wpdb,它是/wp-includes/wp-db.php中定义的wpdb类的实例化。默认情况下,$wpdb被实例化以与WordPress数据库通信。要访问WordPress PHP代码中的$wpdb,请使用global关键字将$wpdb声明为全局变量,或者按以下方式使用超级全局$GLOBALS

global $wpdb;
$results = $wpdb->get_results( 'SELECT * FROM wp_options WHERE option_id = 1', OBJECT );

编辑#2

尝试在type数组的NUMERIC部分中将meta_query的键/值指定为$args

(从https://codex.wordpress.org/Class_Reference/WP_Meta_Query#Accepted_Arguments收集)

$args = array(
    // ...
    'meta_query' => array(
        'relation' => 'AND',
        // ...
        array(
            'key' => $propertyValue,
            'value' => array($data[3], $data[4]),
            'type' => 'NUMERIC',
            'compare' => 'BETWEEN'
        ),
        //...
    )
);

答案 1 :(得分:1)

好的,所以我尝试了所有建议的想法,他们工作得很好。但是,因为我们正在使用高级自定义字段并使用$args ACF建议运行查询,显然您可以执行以下操作:

$args = array(
        'post_type' => $propertyType[0],
        'paged'=>$paged,
        'meta_query' => array(
            'relation' => 'AND',
            array(
                'key' => 'type_of_property',
                'value' => $data[0],
            ),
            array(
                'key' => $propertyValue,
                'value' => array($data[3], $data[4]),
                'type' => 'DECIMAL',
                'compare' => 'BETWEEN'
            ),
            array(
                'key' => 'number_of_bedrooms',
                'value' => $data[2],
                'compare' => 'IN'
            ),
            array(
                'key' => 'town_index',
                'value' => $data[1],
                'compare' => 'IN'
            ),
        )
    );
}
$loop = new WP_Query( $args );

因此,在参数上定义type DECIMAL时,会自动将该字段投射到此摘录中:mt1.meta_key = 'property_value' AND CAST(mt1.meta_value AS DECIMAL) BETWEEN '0' AND '445295' )

答案 2 :(得分:1)

您的值将被比较为STRINGS,这意味着适用的字符串比较规则:

'2' > '3' -> false
'2' > '1999999999' -> true

在你的情况下:

  '2' BETWEEN '0' and '10000'

执行

  ('0' <= '2') && ('2' < '10000')
      (true)   &&    (false)
             false

以及&#39; 2&#39;&lt;&#10;&#39;通过char进行char:

  '2' < '10000'
   a     abcde

运行:

  ('2' < '1') && (null < '0') && (null < '0') etc...
       a               b               c
  (false) && (false) && (false) ....
  false

如果有帮助,只需将您的数字转换为字母:

 1234567890
 abcdefgjij

 '2' BETWEEN '1' AND '100000000'
 'B' BETWEEN 'A' AND 'AJJJJJJJJ'

这显然是错误的