2015-06-02 47 views
0

我试图改变一个Wordpress搜索查询,以便它返回更广泛的结果。THEN语句在SQL查询中

场景:

有一个在数据库中的帖子输入标题“旋转木马手表”。当我搜索这些词(或两者)时,我会返回帖子,这正是我所期望的。

但是,如果我搜索“Carousel Watch Gift”,我没有得到任何结果。

本次搜索的SQL查询如下:

SELECT SQL_CALC_FOUND_ROWS sosen_posts.ID FROM sosen_posts WHERE 1=1 
AND (((sosen_posts.post_title LIKE '%carousel%') OR (sosen_posts.post_content LIKE '%carousel%')) 
    AND ((sosen_posts.post_title LIKE '%watch%') OR (sosen_posts.post_content LIKE '%watch%')) 
    AND ((sosen_posts.post_title LIKE '%gift%') OR (sosen_posts.post_content LIKE '%gift%'))) 
AND (sosen_posts.post_password = '') AND sosen_posts.post_type = 'wp_aff_products' AND (sosen_posts.post_status = 'publish') 
    ORDER BY 
    (CASE WHEN sosen_posts.post_title LIKE '%carousel watch gift%' 
     THEN 1 
     WHEN sosen_posts.post_title LIKE '%carousel%' AND sosen_posts.post_title LIKE '%watch%' AND sosen_posts.post_title LIKE '%gift%' 
     THEN 2 
     WHEN sosen_posts.post_title LIKE '%carousel%' OR sosen_posts.post_title LIKE '%watch%' OR sosen_posts.post_title LIKE '%gift%' 
     THEN 3 
     WHEN sosen_posts.post_content LIKE '%carousel watch gift%' 
     THEN 4 ELSE 5 END), sosen_posts.post_date DESC LIMIT 0, 3 

我的问题是:

  1. 什么查询的一部分阻止返回结果( “Carosuel观察”)?
  2. 我该如何改变它才能得到结果?
  3. 最后,THEN语句在这个查询中做了什么?它是否在WHERE声明中设置了要比较的值?
+0

这里没有THEN语句,只有THEN子句。 (和WHERE相同。) – jarlh

回答

2

THEN关键字用作CASE子句的一部分。一个CASE条款如下:

CASE WHEN expression THEN value WHEN otherexpression THEN othervalue ... END 

表达式的结果是一个单一(有时你看到人们尝试使用CASE子句确定将执行什么样的代码,这将无法正常工作) 。

在此查询中,CASE claues中的值用于确定帖子的排序顺序,并且不影响结果中包含或未包含哪些记录。

要找出结果中包含哪些记录,我们需要剖析WHERE子句。为了便于阅读,我重新格式化了现有子句:

WHERE 1=1 AND (
    (sosen_posts.post_title LIKE '%carousel%' OR sosen_posts.post_content LIKE '%carousel%') 
    AND (sosen_posts.post_title LIKE '%watch%' OR sosen_posts.post_content LIKE '%watch%') 
    AND (sosen_posts.post_title LIKE '%gift%' OR sosen_posts.post_content LIKE '%gift%') 
) AND sosen_posts.post_password = '' AND sosen_posts.post_type = 'wp_aff_products' AND sosen_posts.post_status = 'publish' 

首先,1 = 1部分。这对自动生成的代码很常见。生成器可以将WHERE 1=1放在WHERE子句的开头,无论是否存在任何条件,并且查询仍然有效。然后,对于每个条件,它始终可以使用表格AND condition,而不用担心WHERE子句的先前状态。

进入下一节,我们看到它会根据标题和文本分别检查每个关键字。这些检查通过AND运营商连接。这意味着如果您的帖子在标题或主题的某处中没有gift这个词,它就不会出现在结果中。

最后,这个代码是难以置信的低效。您从不想要看到LIKE运算符与领先的通配符(%),因为它几乎保证您不能使用任何索引来满足该条件。我更像是一个Sql Server人员,但在Sql Server -land中,你想要做的是创建一种特殊的索引,称为full text索引,并使用特殊的CONTAINS()子句编写查询。如果不这样做,你可以使用第三方搜索库,比如Lucene。你从来没有想要使用LIKE查询这样的搜索。我不确定这些替代方案的MySql等效物是什么,但你在这里有什么是而不是你想这样做的方式。

+0

这确实非常有用。我也在我的问题中格式化了sql,这样它可以读得更好一些。但有没有一种简单的方法来改变这个查询(我通过一些钩子只有有限的可能性),以便它返回的结果至少包含任何被搜索的单词?我知道这个查询是低效的,但这是默认情况下的WordPress:/ – luqo33

+0

将我编辑的帖子中缩进的两个'AND'关键字更改为'OR'。 –

+0

该更改是否会保留帖子的排序,以便完全匹配保留在最后的'ORDER BY'子句所指导的顶部? – luqo33

1
  1. LIKE子句要求每个输入单词中的一个或多个存在(我怀疑这是自动发电机的工作方式)。如果您的帖子不包含所有3个单词,则不会因此返回。
  2. 您可以删除“礼物”的LIKE子句,但我认为这会给你相同的代码,就好像刚刚搜索前两个词一样。
  3. 然后是什么是当{TRUE},然后按{} return_this

希望这有助于通过CASE函数返回IE之前。

0

给你的查询一个更好的格式(见下文)它导致在where子句中你正在过滤在标题或内容中有旋转木马的行,请看AND礼物。

case语句只会改变结果的顺序,但如果用这三个词建立查询,它将获取包含所有这些词的行。

SELECT SQL_CALC_FOUND_ROWS sosen_posts.ID FROM sosen_posts 
WHERE 1=1 
     AND (((sosen_posts.post_title LIKE '%carousel%') 
      OR (sosen_posts.post_content LIKE '%carousel%') 
      ) 
      AND ((sosen_posts.post_title LIKE '%watch%') 
       OR (sosen_posts.post_content LIKE '%watch%') 
       ) 
       AND ((sosen_posts.post_title LIKE '%gift%') 
        OR (sosen_posts.post_content LIKE '%gift%') 
        ) 
      ) 
     AND (sosen_posts.post_password = '') 
     AND sosen_posts.post_type = 'wp_aff_products' 
     AND (sosen_posts.post_status = 'publish') 
ORDER BY (CASE WHEN sosen_posts.post_title LIKE '%carousel watch gift%' THEN 1 
       WHEN sosen_posts.post_title LIKE '%carousel%' AND sosen_posts.post_title LIKE '%watch%' AND sosen_posts.post_title LIKE '%gift%' THEN 2 
       WHEN sosen_posts.post_title LIKE '%carousel%' OR sosen_posts.post_title LIKE '%watch%' OR sosen_posts.post_title LIKE '%gift%' THEN 3 
       WHEN sosen_posts.post_content LIKE '%carousel watch gift%' THEN 4 
       ELSE 5 
      END), 
     sosen_posts.post_date DESC 
LIMIT 0, 3 

另请注意,LIMIT 0将返回一个空集。

+0

但是,限制0,3将返回最多3条记录,以偏移量0开始,即第一条可用记录。 –

+0

哎呀!感谢您的更正。 – 1010