【问题标题】:Wordpress query adds INNER/LEFT JOIN. Why or how to remove/prevent INNER/LEFT JOIN?Wordpress 查询添加了 INNER/LEFT JOIN。为什么或如何删除/防止 INNER/LEFT JOIN?
【发布时间】:2017-09-18 10:20:41
【问题描述】:

我正在为 wordpress 中的帖子开发一个过滤器,它使用来自 postmeta 的数据: 我的日期过滤器正在工作并给我这个查询:

工作查询结果:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) 
WHERE 1=1 AND YEAR(wp_posts.post_date)=2017 
AND MONTH(wp_posts.post_date)=03 AND wp_posts.post_type = 'projects' 
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') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 20

当我按 postmeta.meta_value 过滤时,我得到一个额外的 INNER JOIN 导致问题:

过滤器(不完全有效)

$query->set('meta_query', array(
   array(
      'key' => 'project_cust_id',
      'value' => $project_cust_id,
      'compare' => '=' 
   )
));

查询(无效结果)

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) 
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) 
WHERE 1=1 AND ( ( wp_postmeta.meta_key = 'project_cust_id' 
AND wp_postmeta.meta_value = '12345' ) ) AND wp_posts.post_type = 'projects' 
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') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 20

当我将其直接查询到我的数据库时,我在下面没有得到任何结果和错误,但是当我删除额外的行时:INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) 或当我删除行时:LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) 我确实得到了预期的结果。

编辑:MySQL 返回错误:非唯一值表/别名:'wp_postmeta'

我的问题是:

  • 为什么我的代码添加了另一个 INNER JOIN?
  • 如何删除/防止这种额外的 INNER JOIN 或 LEFT JOIN?

任何帮助将不胜感激。

【问题讨论】:

  • 您正在过滤(即删除不匹配的记录),因此 LEFT OUTER JOIN 没有任何意义。
  • 我已经更新了我的帖子/问题,因为我可以删除左连接或内连接,在这两种情况下它都会给我结果。但我仍然不知道如何从我的 SQL 语句中删除其中的 1 个连接。
  • 您在“wp_postmeta”表中没有数据,但在“wp_posts”中有相同的数据。也许您需要考虑一下为什么“wp_postmeta”中没有此 post_id 的数据?
  • 可能是因为“'compare' => '='”?
  • wp_postmeta中有数据,而cust_id不在wp_posts中,通过postmeta中的post_id链接到posts中的id

标签: php mysql wordpress join filter


【解决方案1】:

由于您在 where 子句中过滤 wp_postmeta 表中的值,LEFT JOIN 将像INNER JOIN 一样工作,因为它只会返回在 wp_postmeta 表中具有匹配条件的值。因此,拥有LEFT JOININNER JOIN 或两者都不应该有所作为。如果您希望联接像 LEFT JOIN 一样工作,则应将 wp_postmeta 表的任何条件添加到 JOIN 而不是 WHERE 子句中。

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 

FROM   wp_posts 

       LEFT JOIN wp_postmeta 
       ON wp_posts.ID = wp_postmeta.post_id
       AND wp_postmeta.meta_key = 'project_cust_id' 
       AND wp_postmeta.meta_value = '12345'

WHERE  1=1 AND wp_posts.post_type = 'projects' 
       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') 

GROUP BY wp_posts.ID 

ORDER BY wp_posts.post_date DESC LIMIT 0, 20

【讨论】:

  • 感谢您澄清这一点,但我不能/不知道如何更改查询以从语句中删除 JOIN。而且我不知道如何将它放在 WHERE 子句中,请您给我写一个与对象 $query 一起使用的代码吗?参考:过滤器(不完全工作)
  • 我的意思是如何把它从WHERE子句中去掉,放到JOIN里面
【解决方案2】:

感谢大家的输入,但事实证明我的编码没有问题,显然有一些其他插件在我发送过滤器参数时发送了一个 GET 参数,当设置此参数时返回 FALSE,我通过在该插件中添加 !EMPTY 来修复它,之后它就像一个魅力一样工作。

【讨论】:

    猜你喜欢
    • 2015-01-10
    • 2015-03-03
    • 2019-10-09
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多