排除包含 "x" 的记录的正确模式匹配字符串是什么

What is the correct pattern matching string to exclude records containing "x"

DECLARE @data TABLE
(   sample_text VARCHAR(20))

DECLARE @match TABLE
(   match_text VARCHAR(20),
    return_value INT
)

INSERT INTO @data
VALUES ('sample'),
       ('text'),
       ('fuzzy'),
       ('kittens')

INSERT INTO @match
VALUES ('%e%', 1),
       ('[^t]%', 2),
       ('%[^t]%', 3)

SELECT *
  FROM @data  d 
  JOIN @match m ON d.sample_text LIKE m.match_text

我正在尝试 return 基于字段中的数据是否与正则表达式匹配的值。

正则表达式应该使我能够匹配正数(例如以 T 开头)和负数(例如不以 T 开头)而无需更改基础 SQL.

简单的情况下工作(例如包含“e”,不以“t”开头),但是当我想 return 不包含“t”的行时我遇到了问题。

我知道我可以通过多种方式使用 NOT LIKE,但我正在寻找通用解决方案。

只有 return 值为 3 的行应该是“sample”和“fuzzy”。 “text”和“kittens”不应匹配,因为它们都包含字符“t”。

在我看来 "%[^t]%" 表示“不包含字符 't'”。在您的回答中,您能否阐明它的真正含义?你能用同样的方式翻译你的建议来帮助我理解吗?

您通过反转 LIKE 匹配的意义来排除记录,即:NOT LIKE.

作为一般规则,任何包含 NOT INNOT LIKE 的查询都会大规模执行,但这里有一种方法可以查找与给定模式不匹配的项目。 .

DECLARE @data TABLE
(   sample_text VARCHAR(20))

DECLARE @match TABLE
(   match VARCHAR(20),
    not_match VARCHAR(20),
    return_value INT
)

INSERT INTO @data
VALUES ('sample'),
       ('text'),
       ('fuzzy'),
       ('kittens')

INSERT INTO @match
VALUES ('%e%', null, 1),
       (null, 't%', 2),
       (null, '%t%', 3)

SELECT *
FROM @data  d 
JOIN @match m
  ON (m.match is not null and d.sample_text LIKE m.match)
  OR (m.not_match is not null and d.sample_text NOT LIKE m.not_match);

万一对大家有用...

一如既往,实际问题比我们在这里 post 重现它的最少步骤稍微复杂一些。

我的具体场景涉及匹配 4 个单独的列,因此为每个现有列添加一个新列来表示 NOT LIKE 场景使得一个已经很麻烦的解决方案变得更加麻烦。

鉴于确定模式匹配不会让我到达那里,我确定的解决方案是为 LIKE 场景和 NOT LIKE 场景分别设置行,然后将它们分组一起得出结果。

DECLARE @data TABLE
(   sample_text VARCHAR(20))

DECLARE @match TABLE
(   rule_type    INT, -- 1 = Include, 0 = Exclude
    match_text   VARCHAR(20),
    return_value INT
)

INSERT INTO @data
VALUES ('sample' ),
       ('ample'  ),
       ('dimple' ),
       ('text'   ),
       ('fuzzy'  ),
       ('kittens')

INSERT INTO @match
VALUES ('1', '%mple%', 1),
       ('0', 'd%'    , 1),
       ('1', '[^t]%' , 2),
       ('0', '%mple%', 2)

SELECT sample_text, return_value
  FROM @data  d 
  JOIN @match m ON d.sample_text LIKE m.match_text
 GROUP BY sample_text, return_value
HAVING MIN(rule_type) <> 0 -- any number of "include" rules can match but if any "exclude" rule is matched the record is not returned.