3组配对排除标准

3 sets of paired exclusion criteria

我有订单清单。

我的 table 中有一个 'holds' 列,其中包含串联的保留代码。

我想 return 所有行,包括价格为“0.01”的行,除非价格为“0.01”的行在 OnHold 正文中有 3 个保留代码之一列。

我试图以这种方式处理它:

Select *

From Table

Where NOT (Price='0.01' AND onhold LIKE '%Pricing Hold%') 

AND NOT (Price='0.01' AND  onhold LIKE '%Program  Hold%') 

AND NOT (Price='0.01' AND  onhold LIKE '%Program Hold%')

这排除了价格为“0.01”的所有内容,包括我拥有的行,其中 Price=“0.01”且 onhold=Null。这使我相信我尝试用括号进行的分组不起作用。

我怎样才能拥有 3 组配对标准?

更新:所以,为了解决问题,我更新了查询,只是说:

哪里没有( onhold LIKE '%Pricing Hold%' onhold LIKE '%Program Hold%' onhold LIKE '%Program Hold%' )

所有返回的是 1 条保留值为“.New:Line Hold”的记录,而不是具有 Null 保留值的记录。所以现在我开始思考我是如何使用“NOT LIKE '%%'”的,它会抑制带有空白“onhold”的行。

我觉得是这样的逻辑:

Where Price = '0.01' AND
      onhold NOT LIKE '%Pricing Hold%' AND
      onhold NOT LIKE '%Program  Hold%' AND
      onhold NOT LIKE '%Program Hold%'

我会建议 Price = 0.01。如果将 price 存储为字符串,则应修复数据模型,因此该值将存储为数字(可能是 decimal/numeric)。

I want to return all rows, including the rows that have a price of '0.01', UNLESS the rows with a price of '0.01' have one of 3 hold codes in the body of the OnHold column.

您可以这样表述:

WHERE NOT (
    Price = 0.01
    AND (
        onhold LIKE '%Pricing Hold%' 
        OR onhold LIKE '%Program  Hold%'
        OR onhold LIKE '%Program Hold%'
    )
)

或者,假设 Price 中没有 NULL 值:

WHERE 
    Price <> 0.01
    OR (
        onhold NOT LIKE '%Pricing Hold%' 
        AND onhold NOT LIKE '%Program  Hold%'
        AND onhold NOT LIKE '%Program Hold%'
    )
)

我删除了 '0.01' 周围的单引号:Price 看起来像一个数值,所以它应该这样存储(如果不是这样,你可以恢复它)。

据我所知,您希望排除的唯一行是 price = 0.01 并且在 onhold 中的值是三个 likes 之一的行。

在下面的示例数据中,结果中只应排除第一行

CREATE TABLE #Test (price decimal(10,2), onhold varchar(30));
INSERT INTO #Test (price, onhold)
VALUES                   -- DESIRED RESULT
(0.01, 'Pricing Hold'),  -- Not included
(0.02, 'Pricing Hold'),  -- Included
(0.01, NULL),            -- Included
(0.01, 'No hold'),       -- Included
(0.02, NULL);            -- Included

在您的代码中,不包括第三行 0.01, NULL

一种方法是对您的上述内容进行调整以明确 include/allow NULLS 例如,

SELECT  *
FROM    #Test
WHERE   Price <> 0.01 OR Price IS NULL
        OR onhold IS NULL
        OR NOT (
            onhold LIKE '%Pricing Hold%'
            OR onhold LIKE '%Program  Hold%'
            OR onhold LIKE '%Program Hold%'
            );

您还可以使用 EXCEPT 子句 - 它可读性更强但效率可能较低

SELECT  *
FROM    #Test
  EXCEPT
SELECT  *
FROM    #Test
WHERE   Price = 0.01
        AND (onhold LIKE '%Pricing Hold%'
            OR onhold LIKE '%Program  Hold%'
            OR onhold LIKE '%Program Hold%'
        );

以上两个return以下

price   onhold
0.01    NULL
0.01    No hold
0.02    NULL
0.02    Pricing Hold

这是我的结果 db<>fiddle。值得检查其他答案他们如何处理 NULL 值。