2016-09-08 5 views
1

Я пишу запрос в MS Access¹ по отношению к базе данных Oracle, где я пытаюсь найти всех заключенных в тюрьмах в Норвегии во время переписи 1875 года. Для этого мне нужно искать ключевые слова в нескольких разных полях, так как ennumerators будут описывать свое состояние несколькими различными способами, например:Как запустить общий SQL LIKE-оператор с конкретными исключениями?

  • Описывая их семейное соединение как «Fange», «Arrestant» (заключенный) или подобное.
  • Перечислив их как временно присутствующих в месте под названием «Fængsel» (тюрьма) или подобных.
  • Если у вас в семье, указав их как отсутствующие и называя их предполагаемое местоположение, как указано выше.
  • Перечислив их как живущих в отдельном здании под названием «Fængsel» или подобных.
  • Перечислив свою профессию как «Fange», «Arrestant» (vs.s.) или тому подобное.

Одним из ключевых слов, которые я ищу, являются варианты «Bodsfængsel» («тюрьма покаяния»). Проблемы есть, «Бод» также может означать стойло/небольшое здание. Для того, чтобы убедиться, что я включать все варианты «Bodsfængsel», я написал следующие строки (только соответствующий фрагмент кода показан здесь, полный раздел, как показано ниже):

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

проблема, когда я запускаю это код, я получаю 8513 обращений, точно такое же количество строк, как если бы я исключал строки not like.

Комментарии: Исключения, чтобы избежать попаданий на топонимах, таких как «Тол dbod», «Боде п» или «Told bodg ADE» Если я каким-то образом может получить его для вывода дополнительных полей (например Field0, Field1, Field2 и c.), чтобы показать, где был найден хит, вероятно, было бы намного легче найти ошибки. Надеюсь, я предоставил всю необходимую информацию. Пожалуйста, не отрубите мне голову!

¹ Access 2007 на Win 7 Enterprise.

Полный фрагмент от начала запроса; если это не нужно, пожалуйста, сообщите, и я удалю его:

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 (
    ⋮ 
    ); 
+3

не Если ваш 'or' между каждым' не like' состоянии просто 'and'? Или я чего-то не хватает? Вы также используете '*' в качестве подстановочного знака вместо '%'. Однако вы можете посмотреть на регулярные выражения. –

+0

Вместо поиска 'bod' не лучше ли искать варианты' fængse'? (Я не знаю норвежца, поэтому я могу ошибаться.) Также обратите внимание, что подстановочный знак в Oracle равен%, а не *. – mathguy

+1

Почему вы не используете Oracle Text? Он предназначен для такого рода семантических поисков и содержит множество полезных функций для избежания ложных совпадений. [Узнайте больше] (http://docs.oracle.com/cd/E11882_01/text.112/e24435/toc.htm). – APC

ответ

0

Во-первых, SQL не чувствительны к регистру, поэтому у вас есть лишние линии. Например. эти два делают то же самое:

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

Вы используете or в ваших нижних условиях на уровне, где вы должны использовать and. Если вы используете or, он вернет все записи, потому что, если будет вызван какой-либо из критериев включения, запись будет включена, даже если она не удастся всем остальным на том же уровне. Например, если значение равно 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*" 
     ) 

Или, если вы пытаетесь сделать то, что я думаю, что вы могли бы быть, а именно ищу уникальные комбинации Like и not Like вы недостающие скобки вокруг каждого or/and спаривания , Вы бы добавить их так:

(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*" 
    ) 
) 
+0

Ваш ответ тщательный, полезный и вежливый. Я не знал, что SQL нечувствителен к регистру; зная, что это будет очень полезно. Большое вам спасибо за вашу помощь. –

+0

@CannedMan вы очень желанны! – Rominus