我如何 运行 具有特定排除项的一般 SQL LIKE 语句?

How do I run a general SQL LIKE statement with specific exclusions?

我正在 MS Access¹ 中编写一个针对 Oracle 数据库的查询,我试图在其中找到在 1875 年人口普查期间被关押在挪威监狱中的每个人。为此,我必须在几个不同的领域中搜索关键字,因为调查员会用几种不同的方式描述他们的状态,例如:

我正在寻找的关键字之一是“Bodsfængsel”(“忏悔监狱”)的变体。问题是,“Bod”也可以表示 stall/small building。为了确保包含“Bodsfængsel”的所有变体,我编写了以下几行(此处仅显示相关代码片段;完整部分如下所示):

Or BOSTNVN Like "*bod*"
    And
    (
        BOSTNVN not Like "*bode*" or
        BOSTNVN not Like "*dbod*" or
        BOSTNVN not Like "*bodg*"
    )

问题是,当我 运行 这段代码时,我得到了 8513 次匹配,与我排除 not like 行时的行数完全相同。

评论: 排除是为了避免命中地名,例如“Toldbod”、“Boden”或“Toldbodg阿德' 如果我能以某种方式让它输出额外的字段(例如 Field0、Field1、Field2 等)以显示找到命中的位置,它可能也会更容易找到错误。 我希望我已经提供了所有必要的信息。请不要砍下我的头!

¹ 在 Win 7 Enterprise 上访问 2007。

这是查询开头的完整片段;如果这不是必须的,请指教,我会删除它:

SELECT
    KOMMNR, KRETSNR, BOSTNR, PERSNR,
    ⋮
PID  
FROM
    FOLKETELLINGER_PERSON_1875  
WHERE
    (
        (
            KOMMNR Not Like "11*" 
            And KOMMNR Not Like "12*" 
            ⋮
            And KOMMNR Not Like "17*"
        ) 
        AND (
            SEDVBO Like "*Fæng*" 
            Or SEDVBO Like "*fæng*" 
            ⋮
            Or SEDVBO Like "*arest*"
            And
            (
                SEDVBO not Like "*Bode*" or
                SEDVBO not Like "*dBod*" or
                SEDVBO not Like "*Bodg*"
            )
            Or SEDVBO Like "*bod*"
            And
            (
                SEDVBO not Like "*bode*" or
                SEDVBO not Like "*dbod*" or
                SEDVBO not Like "*bodg*"
            )
            Or SEDVBO Like "*Bot*"
            And
            (
                SEDVBO not Like "*Bote*" or
                SEDVBO not Like "*dBot*" or
                SEDVBO not Like "*Botg*"
            )
            Or SEDVBO Like "*bot*"
            And
            (
                SEDVBO not Like "*bote*" or
                SEDVBO not Like "*dbot*" or
                SEDVBO not Like "*botg*"
            )
        )
    ) 
    OR (
    ⋮
    ); 

首先,SQL不区分大小写,所以你有多余的行。例如。这两个做同样的事情:

Or SEDVBO Like "*Bot*"
Or SEDVBO Like "*bot*"

您在应该使用 and 的最低级别条件下使用 or。如果您使用 or,它将 return 所有记录,因为如果触发了任何一个包含标准,即使它在同一级别未通过所有其他记录,该记录也会被包含在内。例如,如果一个值是 not Like '*Bode*',即使它 like "*dBod*".

,它也会被包括在内

如果代码旨在让语句处于当前级别,您还可以以比必要的更复杂的方式拆分代码。您可以像这样压缩 SEDVBO 块:

SEDVBO Like "*arest*"
Or SEDVBO Like "*bod*"
Or SEDVBO Like "*Bot*"
    And
        (
            SEDVBO not Like "*Bode*" and 
            SEDVBO not Like "*dBod*" and
            SEDVBO not Like "*Bodg*" and
            SEDVBO not Like "*bote*" and
            SEDVBO not Like "*dbot*" and
            SEDVBO not Like "*botg*"
        )

或者,如果您正在尝试做我认为您可能会做的事情,即寻找 Likenot Like 的独特组合,您在每个 or/[ 周围都缺少括号=15=]配对。您可以这样添加它们:

(SEDVBO Like "*arest*"
    And
    (
        SEDVBO not Like "*Bode*" and
        SEDVBO not Like "*dBod*" and
        SEDVBO not Like "*Bodg*"
    )
)
Or 
(SEDVBO Like "*bod*"
    And
    (
        SEDVBO not Like "*bode*" and
        SEDVBO not Like "*dbod*" and
        SEDVBO not Like "*bodg*"
    )
)
Or 
(SEDVBO Like "*bot*"
    And
    (
        SEDVBO not Like "*bote*" and
        SEDVBO not Like "*dbot*" and
        SEDVBO not Like "*botg*"
    )
)

您的第一个片段将变为:

Or 
(BOSTNVN Like "*bod*"
    And
    (
        BOSTNVN not Like "*bode*" and
        BOSTNVN not Like "*dbod*" and
        BOSTNVN not Like "*bodg*"
    )
)