【问题标题】:OR clause affecting an AND clause?OR 子句影响 AND 子句?
【发布时间】:2015-08-26 10:12:42
【问题描述】:

我正在创建一个 SQL 语句,用于在数据库中搜索特定列中的关键字。我需要查询返回符合关键字 1 和关键字 2 条件的记录。这工作得很好,但是我需要允许从多个列中查询关键字。添加 OR 子句后,无法让查询返回对两个关键字都命中的记录而不是一个关键字的结果。

为什么 OR 子句会影响 AND 子句?

如何修改此语句以允许在搜索指定的 3 列时需要两个关键字才能获得成功?

声明:

SELECT CASE WHEN t1.longdesc IS NULL THEN t1.desc 
WHEN t1.longdesc IS NOT NULL THEN t1.longdesc END AS 'description', 
t1.upc 
FROM Items t1 
LEFT JOIN Suppliers t2 ON t1.supplier = t2.supplier_no 
LEFT JOIN Sections t3 ON t1.Section = t3.section_no 
LEFT JOIN Groups t4 on t1.group = t4.group 
WHERE desc LIKE '%keyword1%' 
OR Item_code LIKE '%keyword1%' 
OR certify_code LIKE '%keyword1%' 
AND desc LIKE '%keyword2%' 
OR Item_code LIKE '%keyword2%' 
OR certify_code LIKE '%keyword2%'

【问题讨论】:

    标签: sql sql-server select or-operator and-operator


    【解决方案1】:

    AND 的优先级高于OR。如果您想创建一个条件,逻辑上说“keyword1 在这些列中的任何一个上都匹配,而 keywrod2 在这些列中的任何一个上都匹配”,您需要用括号将每个 ANDs 参数括起来以避免它优先:

    (顺便说一句,选择列表中的描述表达式可以使用coalesce简化)

    SELECT COALESCE (t1.longdesc, t1.desc) AS description, t1.upc 
    FROM Items t1
    LEFT JOIN Suppliers t2 ON t1.supplier = t2.supplier_no 
    LEFT JOIN Sections t3 ON t1.Section = t3.section_no 
    LEFT JOIN Groups t4 on t1.group = t4.group 
    WHERE (desc LIKE '%keyword1%' OR 
           Item_code LIKE '%keyword1%' OR 
           certify_code LIKE '%keyword1%') AND 
          (desc LIKE '%keyword2%' OR 
           Item_code LIKE '%keyword2%' OR 
           certify_code LIKE '%keyword2%')
    

    【讨论】:

    • 感谢您帮助新手!
    【解决方案2】:

    试试这个:

    SELECT 
        ISNULL(t1.longdesc, t1.[desc]) AS 'description'
        , t1.upc 
    FROM Items t1 
    LEFT JOIN Suppliers t2 
        ON t1.supplier = t2.supplier_no 
    LEFT JOIN Sections t3 
        ON t1.Section = t3.section_no 
    LEFT JOIN Groups t4 
        on t1.group = t4.group 
    WHERE 
        ([desc] LIKE '%keyword1%' 
            OR Item_code LIKE '%keyword1%' 
            OR certify_code LIKE '%keyword1%') 
        AND (desc LIKE '%keyword2%' 
            OR Item_code LIKE '%keyword2%' 
            OR certify_code LIKE '%keyword2%')
    

    我清理了你的 case 语句以使用 ISNULL 代替(coalesce 也可以),并在你的 where 逻辑中添加了括号。

    【讨论】:

      【解决方案3】:

      通过使用()() 括起来,将您的WHERE 部分更改为如下所示

      WHERE (
      [desc] LIKE '%keyword1%' 
      OR Item_code LIKE '%keyword1%' 
      OR certify_code LIKE '%keyword1%' 
      )
      AND 
      (
      [desc] LIKE '%keyword2%' 
      OR Item_code LIKE '%keyword2%' 
      OR certify_code LIKE '%keyword2%'
      )
      

      【讨论】:

        【解决方案4】:

        您需要使用括号来使您的逻辑工作。见下文:

         SELECT
          CASE WHEN t1.longdesc IS NULL THEN t1.[desc]
               WHEN t1.longdesc IS NOT NULL THEN t1.longdesc
          END AS 'description',
          t1.upc
         FROM
          Items t1
          LEFT JOIN Suppliers t2
            ON t1.supplier = t2.supplier_no
          LEFT JOIN Sections t3
            ON t1.Section = t3.section_no
          LEFT JOIN Groups t4
            ON t1.[group] = t4.[group]
         WHERE
          (
            [desc] LIKE '%keyword1%'
            OR Item_code LIKE '%keyword1%'
            OR certify_code LIKE '%keyword1%'
          )
          AND (
                [desc] LIKE '%keyword2%'
                OR Item_code LIKE '%keyword2%'
                OR certify_code LIKE '%keyword2%'
              )
        

        【讨论】:

          【解决方案5】:

          我建议你避免使用OR作为性能问题,而使用ISNULL(),所以你可以这样使用:

          SELECT 
              ISNULL(t1.longdesc, t1.desc) AS 'description', 
              t1.upc 
          FROM 
              Items t1 
          LEFT JOIN 
              Suppliers t2 ON t1.supplier = t2.supplier_no 
          LEFT JOIN 
              Sections t3 ON t1.Section = t3.section_no 
          LEFT JOIN 
              Groups t4 on t1.group = t4.group 
          WHERE 
              (desc + ':' + Item_code + ':' + certify_code) LIKE '%keyword1%' 
          AND (desc + ':' + Item_code + ':' + certify_code) LIKE '%keyword2%' 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-02-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-18
            • 1970-01-01
            相关资源
            最近更新 更多