Как написать «заменить» один раз в SQL-запросе, имеющий 3 раза как оператор - PullRequest
1 голос
/ 06 июля 2019

Вот мой sql запрос.Я не хочу писать «заменить» 3 раза.Как я могу оптимизировать это?

select * from table1 where col1='blah' AND 
(
replace(replace(col2,'_',' '),'-',' ') LIKE ? OR 
replace(replace(col2,'_',' '),'-',' ') LIKE ? OR 
replace(replace(col2,'_',' '),'-',' ') LIKE ?
)

Ответы [ 3 ]

2 голосов
/ 06 июля 2019

Вы можете использовать подзапрос:

SELECT *
FROM (
  select *, replace(replace(col2,'_',' '),'-',' ') AS r
  from table1 
  where col1='blah' 
) s
WHERE r LIKE ? OR r LIKE ? OR r LIKE ?

Или LATERAL:

select *
from table1
  ,LATERAL(SELECT replace(replace(col2,'_',' '),'-',' ')  AS r) s
where col1='blah' 
  and (s.r LIKE ? OR s.r LIKE ? OR s.r LIKE ?)

db <> fiddle demo

Я предпочитаю второй подход, потому что нет необходимости вводить внешний запрос.Эта функция была добавлена ​​в версии 8.0.14.

Связано:

1 голос
/ 06 июля 2019

В MySQL вы можете использовать псевдоним столбца в предложении HAVING даже без агрегирования:

select *, replace(replace(col2,'_',' '),'-',' ') as col2_replace
from table1
where col1='blah'
having col2_replace like ?
    or col2_replace like ?
0 голосов
/ 06 июля 2019

MySQL имеет тенденцию материализовать подзапросы - это не только накладные расходы на чтение и запись временной таблицы, но также может повлиять на использование индексов в более сложном запросе.

Вот три альтернативных решениякоторые не требуют подзапросов.

Если ? не содержит подстановочных знаков, то самый простой метод:

 replace(replace(col2, '_', ' '), '-', ' ') in (?, ?, ?)

Если это так, измените логику, чтобы использовать один шаблон регулярного выражения:

 replace(replace(col2, '_', ' '), '-', ' ') regexp ?

Вы также можете явно настроить шаблон в запросе:

 replace(replace(col2, '_', ' '), '-', ' ') regexp
    concat('(',
           replace(replace(?, '_', '.'), '%', '.*'), ')|(',
           replace(replace(?, '_', '.'), '%', '.*'), ')|(',
           replace(replace(?, '_', '.'), '%', '.*'), ')'
          )
...