简体   繁体   English

MySQL查询问题-嵌套和/或语句

[英]mysql query problem - nested and/or statements

I have this query which runs fine: 我有运行良好的此查询:

SELECT count(distinct p.products_id) as total 
FROM (products p 
        LEFT JOIN manufacturers m 
        USING(manufacturers_id), products_description pd, 
              categories c, products_to_categories p2c ) 
LEFT JOIN meta_tags_products_description mtpd 
          ON mtpd.products_id= p2c.products_id 
          AND mtpd.language_id = 1 
WHERE (p.products_status = 1 AND p.products_id = pd.products_id 
       AND pd.language_id = 1 AND p.products_id = p2c.products_id 
       AND p2c.categories_id = c.categories_id 
       AND (
            (pd.products_name LIKE '%3220%' 
             OR p.products_model LIKE '%3220%' 
             OR m.manufacturers_name LIKE '%3220%' 
             OR (mtpd.metatags_keywords LIKE '%3220%' 
                 AND  mtpd.metatags_keywords !='') 
             OR 
             (mtpd.metatags_description LIKE '%3220%' 
              AND   mtpd.metatags_description !='') 
             OR 
              pd.products_description LIKE '%3220%'
            ) 
           ) 
      )

But I want to either search for those WHERE clauses or, given a numeric keyword value as in the example, search for the products id by just adding this to the previous query: 但是我想搜索那些WHERE子句,或者给定一个数字关键字值(如示例中所示),只需将其添加到上一个查询中即可搜索产品ID:

 OR (p.products_id=3220)

But for some reason that addition freezes the mysql server. 但是由于某种原因,添加会冻结mysql服务器。 It just keeps executing the query and it never ends. 它只会继续执行查询,并且永远不会结束。 I have to manually restart the server. 我必须手动重新启动服务器。 What is it that I am doing wrong? 我做错了什么?

When you add the OR to the end (assuming you're adding it after the last paren), you are creating a cartesian join as you're invalidating your JOIN conditions that you placed in your WHERE clause ( p.products_id = pd.products_id , p.products_id = p2c.products_id and p2c.categories_id = c.categories_id ). 当将OR添加到末尾(假设您在最后一个括号之后添加OR)时,您将创建笛卡尔联接,同时使您放置在WHERE子句中的JOIN条件无效( p.products_id = pd.products_idp.products_id = p2c.products_idp2c.categories_id = c.categories_id )。 Also, why are you putting the initial tables (products, manufacturers, products_description, categories, products_to_categories) inside of parenthesis? 另外,为什么还要在括号内放置初始表(产品,制造商,products_description,类别,products_to_categories)? Instead, try something more like this: 相反,请尝试这样的操作:

SELECT count(distinct p.products_id) as total 
FROM products p 
LEFT JOIN manufacturers m USING(manufacturers_id)
LEFT JOIN products_description pd using products_id
LEFT JOIN categories c USING (categories_id)
LEFT JOIN products_to_categories p2c USING (products_id)
LEFT JOIN meta_tags_products_description mtpd 
          ON mtpd.products_id= p2c.products_id 
          AND mtpd.language_id = 1 
WHERE (p.products_status = 1  
       AND pd.language_id = 1  
       AND (
            (pd.products_name LIKE '%3220%' 
             OR p.products_model LIKE '%3220%' 
             OR m.manufacturers_name LIKE '%3220%' 
             OR (mtpd.metatags_keywords LIKE '%3220%' 
                 AND  mtpd.metatags_keywords !='') 
             OR 
             (mtpd.metatags_description LIKE '%3220%' 
              AND   mtpd.metatags_description !='') 
             OR 
              pd.products_description LIKE '%3220%'
            ) 
           ) 
      )
      OR (p.products_id=3220)

I do not understand what p.products_status = 1 AND pd.language_id = 1 mean in your case, so you may need to adjust how those are included in the JOIN. 我不了解p.products_status = 1 AND pd.language_id = 1在您的情况下意味着什么,因此您可能需要调整将这些内容包括在JOIN中的方式。

Using OR is slower than using AND. 使用OR比使用AND慢。 You could try in this case, to put the new condition at the beginning of the WHERE instead of at the end. 在这种情况下,您可以尝试将新条件放在WHERE的开头而不是结尾。

Another solution would bu two write two separate queries, one with all the LIKEs and another using the products_id. 另一种解决方案是两个编写两个单独的查询,一个使用所有LIKE,另一个使用products_id。 Then, use UNION to combine the result of those queries. 然后,使用UNION合并这些查询的结果。 This solution is often faster than using complex expressions with OR. 此解决方案通常比使用带有OR的复杂表达式更快。 UNION ALL is even faster theoretically, but it may result in double records if they match the conditions in both queries. 理论上,UNION ALL甚至更快,但如果两个查询中的条件都匹配,则可能会导致重复记录。

我知道这并不总是可能的,但是如果您可以将LEFT JOIN更改为INNER JOIN,则嵌套的AND / OR子句将更快地工作(它不会入侵您的联接)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM