Что означают "%" и ".-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],'
с результатом объединения следующих
- константа
'%,'
- значение столбца
log.logtypeid
преобразован вvarchar
- константа
'.-1,%'
Итак, предполагая log.logtypeid
содержит значение 42
это создает условие
',~[gpv:lt],' LIKE '%,42.-1,%'
Это может совпадать только если столбец log.logtypeid
содержал значение как ~[gpv:lt]
, Это немного сбивает с толку, поскольку столбцы с именем "id" обычно не содержат "структурированные данные", подобные этим.
Если бы мне пришлось угадывать, я бы сказал, что модель данных сильно нормализована, и в этих столбцах хранятся структурированные данные, разделенные запятыми (возможно, даже пары структурированный ключ / значение).
Другие условия делают что-то подобное.