AND / OR运算符未按要求过滤

时间:2018-09-19 19:06:19

标签: sql sql-server operators

我正在尝试列出标记为“库存”(状态=“ I”)且没有“ FiWipStatusCode”为“ P”,“ B”或“ F”的卡车清单。

换句话说,我想列出标记为“确实”为“ null”或“ C”的“ wiwstatstatuscode”的卡车清单。

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

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)

2 个答案:

答案 0 :(得分:2)

您正在混淆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 :(得分:1)

很多人把这两个运算符混在一起。 在现实生活中,我们说:“把所有的裤子都带给我”,我们希望收到所有这两种物品。

SQL看到请求的方式有所不同,将仅返回带裤子的衬衫以及带裤子的衬衫,但不会仅返回裤子或仅返回衬衫。

在SQL中,如果您想同时使用这两个项目,则需要说“带上所有裤子 OR ”。

以下是一些“良好的经验法则”。

1)如果 AND 两侧的条件 ALL AND 运算符将显示一条记录 ONLY 陈述是正确的。

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

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

希望这会有所帮助。