Что означают "%" и ".-1,%" и ",%" или "%" в SQL/Oracle?

Код, на который я ссылаюсь, это:

AND (
(','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.' || 
    CASE WHEN log.subtype is null 
    THEN ' ' 
    ELSE log.subtype 
    END || ',%')
OR (','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.-1,%')
OR (to_char(log.logtypeid) LIKE 
    CASE 
    WHEN to_char('~[gpv:lt]') = '-1' 
    THEN '%' 
    ELSE ','||to_char('~[gpv:lt]')||',' 
    END)  
)

Любое разъяснение было бы здорово. Спасибо!

3 ответа

Решение

Давайте начнем с этого выражения:

(','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.' || 
    CASE WHEN log.subtype is null 
    THEN ' ' 
    ELSE log.subtype 
    END || ',%')

Вот пример этой идиомы:

','||a||',' LIKE '%,'||b||',%'

в котором a твой lt параметр и b строка типа подтип точки. Это сравнение может использоваться всякий раз, когда у вас есть a строка, представляющая собой список значений, разделенных запятыми, и b Строка, которая является единственным значением, и вы хотите знать, является ли список a содержит значение b,

Чтобы понять, почему это так написано, сначала посмотрите на эту попытку, чтобы сделать это проще:

a LIKE '%'||b||'%'

Мы принимаем b, поставить подстановочный знак в передней и задней части, и сопоставить a, Это будет верно, если a например 1,2,3 а также b является 2, Это также, к сожалению, будет правдой, если a является 12,34,56 а также b является 2, LIKE не выполняет анализ списка через запятую, только сопоставление строк.

Итак, затем вы можете попробовать это:

a LIKE '%,'||b||',%'

Сейчас если b является 2шаблон %,2,% - которая будет соответствовать любой строке, содержащей ,2, так что это верно для aзнак равно1,2,3 и ложь для aзнак равно12,34,56, К сожалению, это также ложно для aзнак равно2,3,4 потому что 2 не имеет запятой перед ним и ложь для aзнак равно0,1,2 потому что 2 не имеет запятой после него.

Для следующего улучшения есть 2 пути. Вы можете использовать отдельные случаи шаблона, чтобы соответствовать b в начале, середине и конце a (если вы пойдете по этому пути, использование регулярного выражения поможет сделать его читабельным!)

Другой способ заключается в изменении a чтобы соответствовать существующему образцу. Мы не совпадали 0,1,2 или же 2,3,4 потому что первый элемент списка и последний элемент списка не окружены запятыми. Но если мы добавим запятую в начале a перед сопоставлением первый элемент списка будет окружен запятыми! И добавьте еще одну запятую в конце a чтобы убедиться, что последний элемент также окружен запятыми.

','||a||',' LIKE '%,'||b||',%'

Теперь когда a является 0,1,2 а также b является 2, LIKE выражение становится:

',0,1,2,' LIKE '%,2,%'

что совпадает! Первый подстановочный знак поглощает ,0,1 и ,2, найден. Последний подстановочный знак соответствует подстроке нулевой длины в конце, что разрешено.

Те -1,% являются строковыми литералами и используются для построения LIKE условие основано на нескольких константах и ​​значениях некоторых столбцов. Это утверждение показывает базовое недопонимание того, как использовать строковые литералы в Oracle.

Возьмем для примера это условие:

','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.-1,%'

to_char('~[gpv:lt]') совершенно бесполезно, потому что он просто преобразует строковую константу '~[gpv:lt]' чтобы... строка. Так что эта часть может быть упрощена до:

',~[gpv:lt],' LIKE '%,' || to_char(log.logtypeid) || '.-1,%'

который по сути говорит:

Сравните строковую константу ',~[gpv:lt],' с результатом объединения следующих

  1. константа '%,'
  2. значение столбца log.logtypeid преобразован в varchar
  3. константа '.-1,%'

Итак, предполагая log.logtypeid содержит значение 42 это создает условие

',~[gpv:lt],' LIKE '%,42.-1,%'

Это может совпадать только если столбец log.logtypeid содержал значение как ~[gpv:lt], Это немного сбивает с толку, поскольку столбцы с именем "id" обычно не содержат "структурированные данные", подобные этим.

Если бы мне пришлось угадывать, я бы сказал, что модель данных сильно нормализована, и в этих столбцах хранятся структурированные данные, разделенные запятыми (возможно, даже пары структурированный ключ / значение).

Другие условия делают что-то подобное.

% известен как Wildcard character, Больше информации здесь.

Другие вопросы по тегам