【问题标题】:AND/OR operator not filtering as desiredAND/OR 运算符未按需要过滤
【发布时间】:2018-09-19 19:06:18
【问题描述】:

我正在尝试提取标记为“库存”(状态 =“I”)且没有“P”、“B”或“F”的“FiWipStatusCode”的卡车列表。

换句话说,我想提取标记为 Inventory 的卡车列表,这些卡车的“fiwipstatuscode”为“null”或“C”。

下面的代码没有按照我想要的方式过滤。 谢谢!

SELECT     InventoryVehicle.StockNo, InventoryVehicle.Status, VehicleSales.FiWipStatusCode
FROM       InventoryVehicle
INNER JOIN VehicleSales ON InventoryVehicle.StockNo = VehicleSales.StockNo
WHERE      (InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode <> 'F') AND (InventoryVehicle.Balance > '15000') OR
           (InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode <> 'P') AND (InventoryVehicle.Balance > 15000) OR
           (InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode <> 'B') AND (InventoryVehicle.Balance > 15000) OR
           (InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode IS NULL) AND (InventoryVehicle.Balance > 15000) OR
           (InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode = 'C') AND (InventoryVehicle.Balance > 15000)

【问题讨论】:

    标签: sql sql-server operators


    【解决方案1】:

    您混淆了 AND 和 OR 的先例。我想你可能想要这个:

    SELECT InventoryVehicle.StockNo, InventoryVehicle.Status, VehicleSales.FiWipStatusCode
    FROM InventoryVehicle INNER JOIN VehicleSales ON InventoryVehicle.StockNo = VehicleSales.StockNo
    WHERE ((InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode <> 'F') AND (InventoryVehicle.Balance > '15000')) OR
                      ((InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode <> 'P') AND (InventoryVehicle.Balance > 15000)) OR
                      ((InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode <> 'B') AND (InventoryVehicle.Balance > 15000)) OR
                      ((InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode is NULL) AND (InventoryVehicle.Balance > 15000)) OR
                      ((InventoryVehicle.Status = 'I') AND (VehicleSales.FiWipStatusCode = 'C') AND (InventoryVehicle.Balance > 15000));
    

    注意 () 封装了每组 AND 检查。

    而且由于现在封装了每组 AND,您可以让它变得更加容易:

    SELECT InventoryVehicle.StockNo, InventoryVehicle.Status, VehicleSales.FiWipStatusCode
    FROM InventoryVehicle INNER JOIN VehicleSales ON InventoryVehicle.StockNo = VehicleSales.StockNo
    WHERE (InventoryVehicle.Status = 'I' AND VehicleSales.FiWipStatusCode <> 'F' AND InventoryVehicle.Balance > '15000') OR
          (InventoryVehicle.Status = 'I' AND VehicleSales.FiWipStatusCode <> 'P' AND InventoryVehicle.Balance > 15000) OR
          (InventoryVehicle.Status = 'I' AND VehicleSales.FiWipStatusCode <> 'B' AND InventoryVehicle.Balance > 15000) OR
          (InventoryVehicle.Status = 'I' AND VehicleSales.FiWipStatusCode is NULL AND InventoryVehicle.Balance > 15000) OR
          (InventoryVehicle.Status = 'I' AND VehicleSales.FiWipStatusCode = 'C' AND InventoryVehicle.Balance > 15000);
    

    而且,由于两种过滤器参数在每种情况下都是相同的,因此您可以进一步简化它:

    SELECT InventoryVehicle.StockNo, InventoryVehicle.Status, VehicleSales.FiWipStatusCode
    FROM InventoryVehicle INNER JOIN VehicleSales ON InventoryVehicle.StockNo = VehicleSales.StockNo
    WHERE InventoryVehicle.Status = 'I'
    AND InventoryVehicle.Balance > '15000'
    AND (
        VehicleSales.FiWipStatusCode <> 'F' OR
        VehicleSales.FiWipStatusCode <> 'P' OR
        VehicleSales.FiWipStatusCode <> 'B' OR
        VehicleSales.FiWipStatusCode is NULL OR
        VehicleSales.FiWipStatusCode = 'C'
    );
    

    【讨论】:

    • 我不得不添加一个左外连接,但它工作得很好!非常感谢!
    • 我什至会更进一步,去掉几乎所有这些括号。他们什么都不做,只是增加了噪音,这使得人们很难看到发生了什么。 +1
    • 我可能在看最终版本时遗漏了一些东西,但是对于 FiWipStatusCode 的值来说,this part not 是真的: VehicleSales.FiWipStatusCode &lt;&gt; 'F' OR VehicleSales.FiWipStatusCode &lt;&gt; 'P'
    • @Richardissimo 是的,我在重读您的评论后删除了该评论。好点,但它仍然是相同的逻辑,尽管有缺陷。
    • ... 所以包含FiWipStatusCode 的整个部分将始终为真。同意,它是原始的,只是在这种形式中更明显。
    【解决方案2】:

    很多人把这两个运算符搞混了。 在现实生活中,我们会说“把所有的裤子衬衫都给我”,我们希望这两样东西都能收到。

    SQL 对请求的看法不同,将只返回裤子搭配衬衫和衬衫搭配裤子,但不会只返回裤子或衬衫。

    在 SQL 中,如果您想要所有这两种物品,则需要说“把所有裤子衬衫带给我”。

    这里有几个“好的经验法则”可以遵循。

    1) AND 运算符在 AND 两边的条件 ALL 时显示记录ONLY陈述属实。

    2) 如果 AND 语句两边的 ANY 条件为真,则 OR 运算符显示一条记录。

    这是 JOIN 语句派上用场的地方。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多