【问题标题】:SQL - Using Logical Operators (where to put parenthesis)SQL - 使用逻辑运算符(括号放在哪里)
【发布时间】:2018-09-11 08:39:06
【问题描述】:

我的查询应该计算上个月特定客户被添加到表中的次数。如果只使用:

WHERE Return_Table.DateAdded >= DATEADD(month, -1, GETDATE())

然后我在上个月得到了所有的“CustomerID”和“TimesReturned”,这似乎是有效的,但是当我使用“AND”和“OR”搜索特定条目时 - 我得到了下面显示的结果,但是这个结果不再计算上个月内的条目。

事实上,当我在搜索中包含或多或少的特定客户时,“TimesReturned”值会发生变化。因此,如果我搜索 'cust1-4' 然后搜索 'cust1-2' - TimesReturned 计数 1 和 2 会发生变化。

我的查询:

SELECT TOP 20 Return_Table.Customer_ID, COUNT(*) AS TimesReturned
FROM Return_Table         
WHERE Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND
 Return_Table.Customer_ID ='cust1' OR
 Return_Table.Customer_ID ='cust2' OR
 Return_Table.Customer_ID ='cust3' OR
 Return_Table.Customer_ID ='cust4'
GROUP BY Return_Table.Customer_ID
ORDER BY TimesReturned DESC

结果:

Customer_ID TimesReturned
   Cust1         24
   Cust2         14
   Cust3         4
   Cust4         2
   .....        ....

虽然这个结果的格式是正确的,但我的查询一定有问题,才能像这样改变值。

【问题讨论】:

    标签: sql sql-server operators logical-operators


    【解决方案1】:

    仔细查看WHERE 子句:

    WHERE Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND
     Return_Table.Customer_ID ='cust1' OR
     Return_Table.Customer_ID ='cust2' OR
     Return_Table.Customer_ID ='cust3' OR
     Return_Table.Customer_ID ='cust4'
    

    它将匹配以下行:

    • 添加的日期是过去一个月,客户 ID = 'cust1'
    • 或客户 ID = 'cust2'
    • 或客户 ID = 'cust3'

    等等。这解释了为什么计数从原始(无客户 ID 过滤器)计数增加。添加括号,你应该很好:

    WHERE
     Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND
     (
     Return_Table.Customer_ID ='cust1' OR
     Return_Table.Customer_ID ='cust2' OR
     Return_Table.Customer_ID ='cust3' OR
     Return_Table.Customer_ID ='cust4'
     )
    

    PS:以上与以下相同:

    WHERE
     Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND Return_Table.Customer_ID ='cust1' OR
     Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND Return_Table.Customer_ID ='cust2' OR
     Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND Return_Table.Customer_ID ='cust3' OR
     Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND Return_Table.Customer_ID ='cust4'
    

    【讨论】:

      【解决方案2】:

      使用 in 运算符代替多个 OR:

      SELECT TOP 20 Return_Table.Customer_ID,
      COUNT(*) AS TimesReturned
       FROM Return_Table         
       WHERE Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND
       Return_Table.Customer_ID in ('cust1' ,'cust2' 'cust3','cust4')
       GROUP BY Return_Table.Customer_ID
       ORDER BY  TimesReturned DESC
      

      【讨论】:

      • 这行得通,但不能解释为什么 OP 的查询不起作用。萨尔曼的回答很好地解释了原因。
      【解决方案3】:

      你需要使用括号,当你将使用多个orand时最好使用括号,否则根据运算符优先级你的结果将被操纵

       SELECT TOP 20 Return_Table.Customer_ID,
            COUNT(*) AS TimesReturned
           FROM Return_Table         
           WHERE Return_Table.DateAdded >= DATEADD(month, -1, GETDATE()) AND
           (Return_Table.Customer_ID ='cust1' OR
            Return_Table.Customer_ID ='cust2' OR
            Return_Table.Customer_ID ='cust3' OR
            Return_Table.Customer_ID ='cust4'
             )
           GROUP BY Return_Table.Customer_ID
      
           ORDER BY  TimesReturned DESC
      

      【讨论】:

      • 我应该命名这个问题 - '如何使用逻辑运算符'?
      • @Mrparkin 你可以
      猜你喜欢
      • 2012-10-01
      • 2015-02-22
      • 2020-02-17
      • 2014-03-16
      • 2011-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多