SQL查询中的THEN语句

时间:2015-06-02 13:49:39

标签: mysql sql

我正在尝试更改Wordpress搜索查询,以便返回更广泛的结果。

情景:

数据库中有一个帖子条目标题“Carousel Watch”。当我搜索这些单词中的任何一个(或两个单词)时,我会收到帖子,这是我期望的。

但是,如果我搜索“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 Watch”)?
  2. 如何更改它以获得返回的结果?
  3. 最后,THEN语句在此查询中的作用是什么?它是否在WHERE语句中设置要比较的值?

3 个答案:

答案 0 :(得分:2)

THEN关键字用作CASE子句的一部分。 CASE子句如下所示:

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

表达式的结果是单个(有时您会看到人们尝试使用CASE子句来确定将执行哪些代码,这不会起作用) 。

在此查询中,CASE条款中的值用于确定帖子的排序顺序,并且与结果中包含或未包含的记录无关。

要找出结果中包含哪些记录,我们需要剖析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索引,并使用特殊的{{来编写查询1}}子句。如果做不到这一点,您可以使用第三方搜索库,例如Lucene。您从不想要对此类搜索使用CONTAINS()次查询。我不确定这些替代品的MySql等价物是什么,但你在这里所拥有的是 not 你想要这样做的方式。

答案 1 :(得分:1)

  1. LIKE子句要求每个输入字中的一个或多个存在(我怀疑这是自动生成器的工作方式)。如果您的帖子不包含所有3个单词,则不会返回。
  2. 你可以删除" Gift"的LIKE子句,虽然我认为这会给你相同的代码,就像你刚搜索前两个单词一样。
  3. 然后是CASE函数返回的内容IE WHEN {true}那么{return_this}
  4. 希望这有帮助。

答案 2 :(得分: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将返回空集。