Похоже, у вас есть четыре возможных комбинации, на которые мы смотрим.
Первый может быть либо «http» или «https», а второй может быть «http» или «https». Четыре возможных комбинации:
http:/ http:/
http:/ https:/
https:/ http:/
https:/ https:/
Пара предложений:
Во-первых, перед тем, как выполнить оператор UPDATE
, в котором мы не уверены, что он собирается делать то, что намеревается сделать, нам нужно написать оператор SELECT
в test выражений. Это позволит нам увидеть результаты выражения, чтобы мы могли убедиться, что оно выполняет то, к чему мы стремимся, в различных условиях тестирования.
Во-вторых, должна быть возможность выделить комбинации (четыре возможности). Если изменения, которые мы применяем, «удаляют» первые http / https, оставляя только одно вхождение ... тогда модификация, которую мы применяем к одному из подмножеств, не сделает строку, а затем перейдет в другое подмножество. (Я понял, что я хотел сказать там, это, вероятно, натолкнулось на искаженное.)
Если у меня есть такая строка
http 1 https 2
и я изменяю это с обновлением на
https 2
Затем последующий прогон по строкам, который не будет совпадать с проверкой для
https https
потому что в строке есть только одно вхождение http.
Предположим, что нас интересуют только строки, в которых строка link
содержит два вхождения http://
/ https://
Мы могли бы использовать регулярное выражение для некоторого сопоставления, или мы можем выдумать его с некоторыми LIKE
сравнениями
SELECT t.link
, t.link LIKE '%http://%http://%' AS c1
, t.link LIKE '%http://%https://%' AS c2
, t.link LIKE '%https://%http://%' AS c3
, t.link LIKE '%https://%https://%' AS c4
FROM (
SELECT 'http://somedomain.com/work-a-link.php?http://someotherdomain.com/thisisworthkeeping.php' AS link
UNION ALL
SELECT 'http://somedomain.com/work-a-link.php?https://someotherdomain.com/thisisworthkeeping.php'
UNION ALL
SELECT 'https://somedomain.com/work-a-link.php?http://someotherdomain.com/thisisworthkeeping.php'
UNION ALL
SELECT 'https://somedomain.com/work-a-link.php?https://someotherdomain.com/thisisworthkeeping.php'
) t
WHERE t.link LIKE '%http%://%http%://%'
AND t.link NOT LIKE '%http%://%http%://%http%://%'
возвращает что-то вроде этого (с некоторой заменой строки в значениях ссылки, чтобы сократить их здесь) ...
link c1 c2 c3 c4
-------------------------------------------------------------- -- -- -- --
http://somedomain.com/walp?http://someotherdomain.com/tiwkp 1 0 0 0
http://somedomain.com/walp?https://someotherdomain.com/tiwkp 0 1 0 0
https://somedomain.com/walp?http://someotherdomain.com/tiwkp 0 0 1 0
https://somedomain.com/walp?https://someotherdomain.com/tiwkp 0 0 0 1
Мы включили условие в предложение WHERE
, чтобы «отфильтровывать» любой URL, где существует более двух вхождений «http [s]: //». (Там есть небольшая путаница, подстановочный знак %
может совпадать с любым количеством символов, поэтому мы не совсем проверяем HTTPS: // и http: // ... (опять же, мы могли бы реализовать обычный выражение выражения (REGEXP или RLIKE), чтобы быть более точным.
Но обратите внимание, как нам удалось «классифицировать» ссылку на значения на c1, c2, c3 и c4.
Подтверждение того, что каждая ссылка попадает в одну категорию,
Мы можем включить дополнительное выражение в список SELECT
, CASE
WHEN t.link LIKE '%http://%http://%' THEN 'c1'
WHEN t.link LIKE '%http://%https://%' THEN 'c2'
WHEN t.link LIKE '%https://%http://%' THEN 'c3'
WHEN t.link LIKE '%https://%https://%' THEN 'c4'
ELSE NULL
END
Если мы находим подходящее условие WHEN, мы возвращаем THEN, и все готово. (Если есть перекрытие, ссылка, которая попадает в более чем одну категорию, мы не увидим ее в этом выражении.)
link c c1 c2 c3 c4
-------------------------------------------------------------- -- -- -- -- --
http://somedomain.com/walp?http://someotherdomain.com/tiwkp c1 1 0 0 0
http://somedomain.com/walp?https://someotherdomain.com/tiwkp c2 0 1 0 0
https://somedomain.com/walp?http://someotherdomain.com/tiwkp c3 0 0 1 0
https://somedomain.com/walp?https://someotherdomain.com/tiwkp c4 0 0 0 1
Мы можем тестировать с различными значениями link
, различными шаблонами и проверять, что наша подходящая «категоризация» работает так, как мы намереваемся.
(Этот метод использования оператора SELECT для проверки выражений и особенно функций, с которыми мы не знакомы ... с SUBSTRING_INDEX, что возвращается, когда строка поиска не найдена? Чувствительна ли к регистру функция REPLACE? И и так далее.)
Мы можем настраивать и настраивать, экспериментировать и находить правильные комбинации, чтобы все работало так, как мы хотим. Как только мы получим это,
Мы можем включить еще одно выражение в список SELECT. Мы скопируем только что добавленное, но на этот раз вместо возврата литерала мы добавим другое выражение, которое выполняет функции SUBSTRING_INDEX
и REPLACE
.
Поскольку мы запускаем SELECT
, мы знаем, что не собираемся искажать / изменять содержимое таблицы. Мы просто тестируем некоторые выражения, чтобы увидеть, что они возвращают.
, CASE
WHEN t.link LIKE '%http://%http://%' -- 'c1'
THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))
WHEN t.link LIKE '%http://%https://%' -- 'c2'
THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))
WHEN t.link LIKE '%https://%http://%' -- 'c3'
THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))
WHEN t.link LIKE '%https://%https://%' -- 'c4'
THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))
ELSE NULL
END AS new_link
И довольно скоро мы получим такой результат ...
link new_link
------------------------------------------------------------- ---------------------------------
http://somedomain.com/walp?http://someotherdomain.com/tiwkp http://someotherdomain.com/tiwkp
http://somedomain.com/walp?https://someotherdomain.com/tiwkp https://someotherdomain.com/tiwkp
https://somedomain.com/walp?http://someotherdomain.com/tiwkp http://someotherdomain.com/tiwkp
https://somedomain.com/walp?https://someotherdomain.com/tiwkp https://someotherdomain.com/tiwkp
Как только у нас работает работающее выражение, которое возвращает значение new_link
, которое мы хотим присвоить столбцу, вместо значения link
,
(и мы сначала запустим тестовую копию таблицы)
Мы можем преобразовать наш оператор SELECT в ОБНОВЛЕНИЕ
заменить SELECT ... FROM
на UPDATE
и добавьте предложение SET
, чтобы назначить выражение new_link для ссылки
(замените NULL в ELSE ссылкой на столбец, чтобы в случае, если мы выполним все условия, которые мы проверяем в CASE, мы не будем изменять эту строку ...)
UPDATE mytesttable t
SET t.link
= CASE
WHEN t.link LIKE '%http://%http://%' -- 'c1'
THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))
WHEN t.link LIKE '%http://%https://%' -- 'c2'
THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))
WHEN t.link LIKE '%https://%http://%' -- 'c3'
THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))
WHEN t.link LIKE '%https://%https://%' -- 'c4'
THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))
ELSE t.link
END
WHERE t.link LIKE '%http%://%http%://%'
AND t.link NOT LIKE '%http%://%http%://%http%://%'
Но прежде чем запустить UPDATE, мы должны протестировать наши выражения с различными значениями ссылок, включая крайние и угловые регистры.
И еще раз обратите внимание, что те сравнения LIKE
, которые я написал, потенциально могут совпадать со шаткими строками, которые мы, возможно, не хотим сравнивать, например. http://BLAH http DERP :// flurb http://
.
Похоже, что мы должны также проверять вопросительный знак перед вторым появлением http
.
Мы бы получили более точное сопоставление с образцом, используя регулярные выражения, сравнение с REGEXP (RLIKE).
Тема остается прежней ... сначала протестируйте выражения с помощью SELECT, а затем запустите ОБНОВЛЕНИЕ.