【问题标题】:An 'OR' operator is returning too many rows\'OR\' 运算符返回太多行
【发布时间】:2023-01-10 16:40:17
【问题描述】:

我对下一个代码有疑问:

--Declare variables to represent the field names, values, and exclude list

DECLARE @DateDifference AS INT = 180;
DECLARE @QuantityDispensedDays AS INT = 12;
DECLARE @DaysSupplyMin AS INT = 1;
DECLARE @DaysSupplyMax AS INT = 168;
DECLARE @y AS VARCHAR(50) = '';
DECLARE @DateLimit1 AS DATE = '2019-12-04';


-- Define a Common Table Expression (CTE) with the WITH statement

WITH combined_tables AS (
    SELECT *
    FROM [dbo].[Table1]
    UNION ALL
    SELECT *
    FROM [dbo].[Table2]
    UNION ALL
    SELECT *
    FROM [dbo].[Table3]
)

-- Select from the CTE and apply filters

SELECT DISTINCT *, DATEDIFF(DAY,CAST(SUBSTRING(DateWritten,1,10) AS DATE), CAST(SUBSTRING(DateFilled,1,10) AS DATE)) AS DateDif
FROM combined_tables
WHERE
CAST(SUBSTRING(DateFilled,1,10) AS DATE) < @DateLimit1
OR
( DATEDIFF(DAY,CAST(SUBSTRING(DateWritten,1,10) AS DATE), CAST(SUBSTRING(DateFilled,1,10) AS DATE)) <= @DateDifference
AND PharmacyNPI NOT IN(
    1,2,3...)
AND PharmacyNABP NOT IN(
    1,2,3...)
AND QuantityDispensed <= @QuantityDispensedDays
AND DaysSupply BETWEEN @DaysSupplyMin AND @DaysSupplyMax
);

给我大约 300 行,而不仅仅是单独执行 3 个表的联合。

此外,如果我评论第一个条件并且“或”语句按应有的方式应用过滤器

--Declare variables to represent the field names, values, and exclude list

DECLARE @DateDifference AS INT = 180;
DECLARE @QuantityDispensedDays AS INT = 12;
DECLARE @DaysSupplyMin AS INT = 1;
DECLARE @DaysSupplyMax AS INT = 168;
DECLARE @y AS VARCHAR(50) = '';
DECLARE @DateLimit1 AS DATE = '2019-12-04';


-- Define a Common Table Expression (CTE) with the WITH statement

WITH combined_tables AS (
    SELECT *
    FROM [dbo].[Table1]
    UNION ALL
    SELECT *
    FROM [dbo].[Table2]
    UNION ALL
    SELECT *
    FROM [dbo].[Table3]
)

-- Select from the CTE and apply filters

SELECT DISTINCT *, DATEDIFF(DAY,CAST(SUBSTRING(DateWritten,1,10) AS DATE), CAST(SUBSTRING(DateFilled,1,10) AS DATE)) AS DateDif
FROM combined_tables
WHERE
--CAST(SUBSTRING(DateFilled,1,10) AS DATE) < @DateLimit1
--OR
( DATEDIFF(DAY,CAST(SUBSTRING(DateWritten,1,10) AS DATE), CAST(SUBSTRING(DateFilled,1,10) AS DATE)) <= @DateDifference
AND PharmacyNPI NOT IN(
    1,2,3...)
AND PharmacyNABP NOT IN(
    1,2,3...)
AND QuantityDispensed <= @QuantityDispensedDays
AND DaysSupply BETWEEN @DaysSupplyMin AND @DaysSupplyMax
);

现在我少了 2K 行,这是应该的

但问题是我还需要我刚刚评论的限制。

有没有人知道发生了什么或我可以使用什么替代方案?

如上所述。但

【问题讨论】:

  • 您确定要“或”吗?听起来你想要“AND”?
  • 我需要我的结果在没有任何条件的情况下拥有该日期之前的所有数据,然后,对于具有 datediff 标准的任何行以及该日期和之后的代码排除
  • 您可能需要在 WHERE 中加上一些括号; AND 在 OR 之前解决。就目前而言,您要过滤的是 A OR (B AND C AND D AND E AND F) 但您可能想要 (A OR B) AND C AND D AND E AND F
  • 根据您所说的条件是正确的,您将必须提供一个 minimal reproducible example 来证明正在返回的行,您认为这些行不符合 WHERE 标准。
  • @RickyTillson 不是基于 OPS 评论“我需要我的结果在没有任何条件的情况下拥有该日期之前的所有数据” - 但它似乎按预期工作。

标签: sql sql-server


【解决方案1】:

括号在MYSQL的逻辑语法中是极其重要的。

AND 和 OR 要求您以特定方式使用括号,当您想要应用逻辑而不是默认编译器对逻辑的解释时。

就像你的 cmets 中提到的 RickyTillson 一样,你的括号使用对于你的预期结果来说似乎是有缺陷的,但是如果没有以下信息就很难验证这一点:你得到了什么,你期望什么,最好是叙述你为什么期望不同的结果。

然而:

我愿意尝试将此作为您可以做什么的可能示例:

DECLARE @DateDifference AS INT = 180;
DECLARE @QuantityDispensedDays AS INT = 12;
DECLARE @DaysSupplyMin AS INT = 1;
DECLARE @DaysSupplyMax AS INT = 168;
DECLARE @y AS VARCHAR(50) = '';
DECLARE @DateLimit1 AS DATE = '2019-12-04';


-- Define a Common Table Expression (CTE) with the WITH statement

WITH combined_tables AS (
    SELECT *
    FROM [dbo].[Table1]
    UNION ALL
    SELECT *
    FROM [dbo].[Table2]
    UNION ALL
    SELECT *
    FROM [dbo].[Table3]
)

-- Select from the CTE and apply filters

SELECT DISTINCT *, DATEDIFF(DAY,CAST(SUBSTRING(DateWritten,1,10) AS DATE), CAST(SUBSTRING(DateFilled,1,10) AS DATE)) AS DateDif
FROM combined_tables
WHERE
(CAST(SUBSTRING(DateFilled,1,10) AS DATE) < @DateLimit1
OR
( DATEDIFF(DAY,CAST(SUBSTRING(DateWritten,1,10) AS DATE), CAST(SUBSTRING(DateFilled,1,10) AS DATE)) <= @DateDifference)
AND PharmacyNPI NOT IN(
    1,2,3...)
AND PharmacyNABP NOT IN(
    1,2,3...)
AND QuantityDispensed <= @QuantityDispensedDays
AND DaysSupply BETWEEN @DaysSupplyMin AND @DaysSupplyMax
);

请注意,这不是相同的代码,它是您的初始逻辑语句(OR 的左侧)和您的下一个逻辑语句(OR 的右侧)周围的括号

这应该根据我认为你想要的来隔离逻辑。

我也可能是错的 :D

【讨论】:

    猜你喜欢
    • 2019-02-09
    • 2020-01-20
    • 1970-01-01
    • 2015-07-08
    • 2014-12-18
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多