使用BETWEEN查询元字段

时间:2013-02-01 作者:Kristian Primdal

我试图查询一些格和逻辑,然后我得到一些长的数字,显然查询不喜欢这样。

假设我在数据库中有这些

Meta-key: lat 
Meta-value: 54.3415000 
Meta-key: lng
Meta-value: 10.1254100
然后执行如下查询:

$args[\'meta_query\'] = 
        array(
            \'relation\' => \'AND\', 
            array(
                \'key\'       => \'lat\',
                \'value\'     =>  array( \'53.82659686199116\', \'54.946076335668714\' ),
                \'type\'      => \'NUMERIC\',
                \'compare\'   => \'BETWEEN\',
            ),
            array(
                \'key\'       => \'lng\',
                \'value\'     =>  array( \'8.429260683593725\', \'11.889954042968725\' ),
                \'type\'      => \'NUMERIC\',
                \'compare\'   => \'BETWEEN\',
            )
        );
然后就行了,BUT, 当它看起来像这样时:

$args[\'meta_query\'] = 
        array(
            \'relation\' => \'AND\', 
            array(
                \'key\'       => \'lat\',
                \'value\'     =>  array( \'54.10933293482647\', \'54.66906633195788\' ),
                \'type\'      => \'NUMERIC\',
                \'compare\'   => \'BETWEEN\',
            ),
            array(
                \'key\'       => \'lng\',
                \'value\'     =>  array( \'9.294434023437475\', \'11.024780703124975\' ),
                \'type\'      => \'NUMERIC\',
                \'compare\'   => \'BETWEEN\',
            )
        );
然后它就不起作用了,即使它仍然在两个数字之间。

有人知道这是怎么回事吗?一定是MYSQL的东西。

EDIT:

以下是mysql请求的外观:

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) WHERE 1=1 AND wp_posts.post_type = \'branchenbuch\' 
AND (wp_posts.post_status = \'publish\' OR wp_posts.post_status = \'future\' 
OR wp_posts.post_status = \'draft\' OR wp_posts.post_status = \'pending\' 
OR wp_posts.post_status = \'private\') AND ( (wp_postmeta.meta_key = \'lat\' 
AND CAST(wp_postmeta.meta_value AS SIGNED) BETWEEN \'54.1833340338\' 
AND \'54.4636527622\')AND (mt1.meta_key = \'lng\' AND CAST(mt1.meta_value AS SIGNED) 
BETWEEN \'9.76272625977\' AND \'10.6278995996\') ) GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 10 

2 个回复
SO网友:s_ha_dum

您的问题是:

CAST(wp_postmeta.meta_value AS SIGNED)
运行一个简单的SQL查询(命令行或PhpMyAdmin,无论您喜欢什么)SELECT CAST(\'1.2\' as SIGNED) 您将看到返回的值是1. 是什么导致了这种情况\'type\' => \'NUMERIC\',.

你可以通过DECIMALmeta_query 而不是NUMERIC 但我看不到将参数传递给DECIMAL 这实际上会使它变得有用。SELECT CAST(\'1.2\' as DECIMAL) 也是1 除非您还将参数传递给DECIMAL 像这样SELECT CAST(\'1.2\' as DECIMAL(20,10)). 第一个数字是“精度”——数学中使用的小数位数——第二个是返回的小数位数。在我看来,第二个值需要至少比第一个值小2,否则会出现奇怪的舍入问题。显然,第二个数字必须等于或大于数字中的最大小数位数。

最好的方法是\'type\' => \'DECIMAL\', 并应用过滤器:

function add_decimal_params($sqlarr) {
  remove_filter(\'get_meta_sql\',\'add_decimal_params\');
  $sqlarr[\'where\'] = str_replace(\'DECIMAL\',\'DECIMAL(20,16)\',$sqlarr[\'where\']);
  return $sqlarr;
}
add_filter(\'get_meta_sql\',\'add_decimal_params\');
在查询之前添加过滤器,它将删除自身。

may 通过将数字填充到相同的长度,而不是使用type 这是一个争论,但我并没有对此进行测试。

SO网友:Amit

几年前,我使用了类似的东西,我最终使用了原始sql(不记得为什么),但我从您的原始sql和我的原始sql中看到的主要区别是这一行:

AND CAST(wp_postmeta.meta_value AS SIGNED) BETWEEN \'54.1833340338\' 
在我的例子中,它被转换为十进制,值是数字(不是字符串):

AND CAST(wp_postmeta.meta_value AS DECIMAL(20,10)) BETWEEN 54.1833340338 
而实际lat/lng没有单引号->所以它们是实际数字。

尝试运行以下操作:

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) WHERE 1=1 AND wp_posts.post_type = \'branchenbuch\' 
AND (wp_posts.post_status = \'publish\' OR wp_posts.post_status = \'future\' 
OR wp_posts.post_status = \'draft\' OR wp_posts.post_status = \'pending\' 
OR wp_posts.post_status = \'private\')

AND ( (wp_postmeta.meta_key = \'lat\' 
AND CAST(wp_postmeta.meta_value AS DECIMAL(20,10))
BETWEEN 54.1833340338 AND 54.4636527622)

AND (mt1.meta_key = \'lng\'
AND CAST(mt1.meta_value AS DECIMAL(20,10)) 
BETWEEN 9.76272625977 AND 10.6278995996))

GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 10 

结束

相关推荐

如何通过命令行导出/导入WordPress(MySQL)数据库?

通常,可以使用以下简单的SSH命令导出和导入MySQL数据库:Export:mysqldump -u USERNAME -p DATABASE_NAME > filename.sql Import:mysql -u USERNAME -p DATABASE_NAME < filename.sql 但说到WordPress,就没那么简单了。据我所见,需要提及其他参数,例如--add-drop-table 例如。WordPress Codexprovide some info,