看起来您总共有四种可能的组合我们正在研究。
第一个可以是“http”或“https”,第二个可以是“http”或“https”。四种可能的组合:
http:/ http:/
http:/ https:/
https:/ http:/
https:/ https:/
几个建议:
首先,在我们执行 UPDATE 语句之前,我们不确定它是否会按照我们的意图执行,我们应该编写一个 SELECT 语句来测试表达式.让我们看看表达式的结果,这样我们就可以在各种测试条件下验证它是否按照我们的意图进行。
其次,应该可以分离出组合(四种可能性)。如果我们正在应用的更改是“删除”第一个 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 子句中添加了一个条件,以“过滤掉”出现两次以上“http[s]://”的任何 URL。 (这里有一点点捏造,% 通配符可以匹配任意数量的字符,所以我们不完全检查 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 语句转换为 UPDATE
将SELECT ... FROM 替换为UPDATE
并添加一个SET 子句以将 new_link 表达式分配给链接
(将 ELSE 中的 NULL 替换为对该列的引用,因此,如果我们遇到了在 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 测试表达式,然后运行 UPDATE。