【问题标题】:Wordpress SQL query with multiple taxonomies具有多种分类法的 Wordpress SQL 查询
【发布时间】:2012-06-22 07:51:21
【问题描述】:

我正在开展一个项目,该项目在输入的半径范围内显示帖子类型,该半径按与目标地址的距离排序。 现在我正在使用这个工作正常的查询:

sql = " SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, ( " . $_GET['mikm'] . " *           acos( cos( radians( $lat ) ) * cos( radians( wposts.lat ) ) * cos( radians( wposts.long ) - radians( $long ) ) + sin( radians( $lat ) ) * sin( radians( wposts.lat) ) ) )  AS distance  
    FROM post_address  wposts 
    WHERE wposts.post_type ='" . $post_type . "'
    HAVING distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page;


post_address 是一个包含帖子 ID、帖子类型和地址的表。当使用地址保存或更新帖子时,该表正在使用信息进行更新。 我使用的表格有地址字段、选择英里或公里的复选框以及下拉菜单中的距离。我使用 get 方法和表单进行分页。

虽然上面的查询工作正常,但我正在尝试添加分类法支持。我设法使用

使其适用于一种分类法
wp_dropdown_categories($tax_name)


和 SQL:

SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, ( " . $_GET['mikm'] . " * acos( cos( radians( $lat ) ) * cos( radians( wposts.lat ) ) * cos( radians( wposts.long ) - radians( $long ) ) + sin( radians( $lat ) ) * sin( radians( wposts.lat) ) ) )  AS distance  
FROM post_address  wposts
LEFT JOIN $wpdb->term_relationships ON (wposts.post_id = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
WHERE wposts.post_type ='" . $post_type . "'
AND $wpdb->term_taxonomy.taxonomy IN ('" $tax_name "')
AND ($wpdb->term_taxonomy.parent IN (" . $_GET[$tax_name] . ") OR $wpdb->term_taxonomy.term_id IN (" . $_GET[$tax_name] . "))
HAVING distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page;


现在,由于一种分类法工作正常,我想让它与多种分类法一起工作,这就是我卡住的地方。例如,如果帖子类型“汽车”有 2 个分类法“模型”和“颜色”,我希望能够过滤具有“这个”模型和“这个”颜色的帖子。我不知道帖子类型存在多少分类法(曾经使用此插件的人将在管理设置中手动输入)并且它们现在被保存在数组中。例如 $taxonomies = array('car_model','car_color') 我可以使用以下方法填充类别下拉列表:

`
foreach ($taxonomies as $tax) {
echo     '<div id="' . $tax . '_cat">';
echo       '<label for="category-id">Choose category: </label>';
        custom_taxonomy_dropdown($tax); 
echo     '</div>';    
`



function custom_taxonomy_dropdown($tax_name) {
$args = array(
        'taxonomy'          => $tax_name,
        'hide_empty'        => 0,
        'depth'             => 10,
        'hierarchical'      =>  1,
        'id'                =>  $tax_name . '_id',
        'name'              => $tax_name,
        'selected'          => $_GET[$tax_name],
        'show_option_all'   => 'All categories',
        );      
wp_dropdown_categories($args); 
} 


下拉菜单工作正常,输出也被发送到 url,但我无法找到使其工作的 SQL 查询。

这是我的第一个项目。如果这个问题太长了,请原谅我,但我试图尽可能清楚。我也不确定上面的任何代码是否是最好的方法,但任何人的帮助将不胜感激。

更新:

下面是我现在使用的代码,它适用于多种分类法。但是,我仍然遇到一些问题。当我在所有分类法中选择“所有类别”时,sql 将如下所示:

AND $wpdb->term_taxonomy.term_id IN () 

并且计数将显示 count(*) = 0 ,它不会带来任何结果而不是所有结果。

其他问题是子和孙类别。当我选择父类别时,我希望获得其所有子类别和孙类别的结果。但由于没有帖子附加到父类别,而是附加到其子类别,我没有得到任何结果。 这是我现在的代码:

    "SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, (" . $_GET['mikm'] . "* acos( cos( radians( $lat ) ) * cos( radians( wposts.lat ) ) * cos( radians( wposts.long ) - radians( $long ) ) + sin( radians( $lat ) ) * sin( radians( wposts.lat) ) ) )  AS distance 
        FROM posts_address  wposts
        LEFT JOIN $wpdb->term_relationships ON (wposts.post_id = $wpdb->term_relationships.object_id)
        LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
        LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
    WHERE 
    wposts.post_type IN ('" . $post_type . "')

    AND $wpdb->term_taxonomy.term_id IN (" . $total_terms .") 
    GROUP BY wposts.post_id, wposts.lat, wposts.long        
        HAVING count(*) = " . $bc . " AND distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page  ;

如有任何帮助,我们将不胜感激。

【问题讨论】:

  • 这种行为可能意味着,对于wordpress,不选择类别意味着选择所有类别。这带来了一个问题,因为我描述的方法需要知道有多少类别。我会测试没有选择类别的情况,并在 PHP 代码中将查询参数更改为所有分类类别的列表(即去掉最不意味着“所有类别”的空类别)
  • s/空类别最少/空类别列表/
  • 这就是我现在正在做的事情。当没有类别选择时,我正在尝试创建一个案例。对于子孙类别,我正在稍微调整代码。我必须使用 get_term_children() 运行 foreach 循环来检查我选择的术语是否为父项,如果是则获取其子项 ID。然后我使用这些 id 来运行 sql。否则它将运行我选择的术语。我快到了。再次感谢。这是对这个社区的热烈欢迎。你帮了我很多。

标签: sql wordpress taxonomy


【解决方案1】:

如果我正确阅读了您的要求,您无需从数据库中提取有关分类的信息,只需验证帖子是否“加入”了所有必需的分类。使用所有必需的分类法加入帖子,然后根据行乘结果进行过滤。

第一步,你有的地方

$wpdb->term_taxonomy.taxonomy IN ('" $tax_name "')

$wpdb->term_taxonomy.parent IN (" . $_GET[$tax_name] . ") OR $wpdb->term_taxonomy.term_id IN (" . $_GET[$tax_name] . "))

让进入 IN 运算符的参数生成所有分类名称的列表,逗号分隔,用引号括起来。例如:

$wpdb->term_taxonomy.taxonomy IN ('model_a', 'color_blue')

现在,查询会将帖子与帖子匹配的所有分类(在您的过滤器中)相乘。从这里开始,这很简单:按帖子字段分组(您只需按查询中输出的字段分组),并使用 HAVING 进行过滤,以便您只返回帖子乘以所有类别。在这个例子中,帖子应该匹配两个类别,所以:

(...)
GROUP BY wposts.post_id, wposts.lat, wposts.long
HAVING count(*) = 2 AND (distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page);

请注意,count(*) 过滤器应与匹配的分类“轴”的数量相匹配。另请注意,我假设分类法中没有冲突(即没有“蓝色”模型和“蓝色”颜色)。

您可能应该删除查询中的 DISTINCT 运算符(分组已经产生不同的帖子,我不确定 mysql 的优化器何时会计算不同的运算符)。

【讨论】:

  • 谢谢塞尔吉奥,我试过你的解决方案,但我无法让它工作。我认为您建议在其中输入分类法 $wpdb->term_taxonomy.taxonomy ('model_a', 'color_blue') IN 它应该是 term_taxonomy.term_id IN 以及我从下拉列表中选择的术语 id。在这种情况下,我会收到我选择的模型或我选择的颜色的帖子。当我只需要具有我选择的模型和颜色的帖子时。
  • 你已经完成了一半。尝试不分组的查询,你应该得到所有的帖子,分类法对。然后,如果您按帖子字段分组并生成计数(),您应该会得到帖子以及它匹配的分类法。然后,在 HAVING 子句中添加 count() 条件,您就可以筛选出符合所有所需分类的帖子。
  • 非常感谢,这次确实奏效了。由于“AND(距离...)”中的括号,我第一次尝试时没有得到结果。在我删除它们之后它起作用了。但是,我现在仍然遇到一些其他问题。我用我现在使用的代码和我遇到的问题更新了我的问题。有关这些问题的任何其他信息将对我非常有帮助。我仍然将您的答案标记为正确答案,因为它解决了我原来的问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 2012-06-13
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多