这个问题围绕使用CONCAT和SUBSTRINGS来更新mysql TABLE中的内容
如果我的链接存储在由
组成的mysql数据库中https://this.example.com/work-a-link.php?https://that.example.com/thisisworthkeeping.php
以下代码将删除第一个实例,并保留url的第二个实例,其前缀为http:// url(理论上,在这种情况下,它应该是https:// - 因为第二个URL开头是HTTPS://
DROP TABLE IF EXISTS content_temp;
CREATE TABLE content_temp AS SELECT * FROM content GROUP BY Title ORDER BY ID ASC;
UPDATE content_temp SET link = CONCAT('http://', SUBSTRING_INDEX(link, 'https://', -1));
UPDATE content_temp SET link = CONCAT('http://', SUBSTRING_INDEX(link, 'http://', -1));
UPDATE content_temp SET link=replace(link,'http://https://','http://');
UPDATE content_temp SET link=replace(link,'http://http://','http://');
这就是问题,我正在寻求能帮助我或指出正确方向的人的帮助 - 我希望第二个实例中的任何https://
保留为https://
- 而我的密码将其改为http://
我想要完成的是尊重和保留第二个实例 - 无论是http还是https。
所有这一切中唯一的其他随机因素是第一个实例可能是http或https
因此重新调整此代码的最终结果将是:
(A)
http://this.example.com/work-a-link.php?http://that.example.com/thisisworthkeeping.php
会给http://that.example.com/thisisworthkeeping.php
。
(B)
http://this.example.com/work-a-link.php?https://that.example.com/thisisworthkeeping.php
会给https://that.example.com/thisisworthkeeping.php
。
(C)
https://this.example.com/work-a-link.php?http://that.example.com/thisisworthkeeping.php
会给http://that.example.com/thisisworthkeeping.php
。
和
(D)
https://this.example.com/work-a-link.php?https://that.example.com/thisisworthkeeping.php
会给https://that.example.com/thisisworthkeeping.php
。
答案 0 :(得分:0)
如果要更改的所有链接都包含子字符串.php?
,则可以执行以下操作:
UPDATE content_temp SET link = SUBSTRING_INDEX(link, '.php?', -1)
WHERE link LIKE '%.php?%'
专业提示:在WHERE
操作上放置UPDATE
子句总是一个好主意:没有它SQL会更新表中的所有行。这可能会破坏表格,并且可能会破坏事务日志。
答案 1 :(得分:0)
看起来你们总共有四种可能的组合。 第一个可以是“http”或“https”,第二个可以是“http”或“https”。四种可能的组合:
http:/ http:/
http:/ https:/
https:/ http:/
https:/ https:/
一些建议:
首先,在我们执行UPDATE
语句之前,我们不确定它是否会按照我们的意图去做,我们应该在 test }中写一个SELECT
语句em>表达式。这让我们看到了表达式的结果,因此我们可以在各种测试条件下验证它是否正在按照我们的意图行事。
其次,应该可以将组合分开(四种可能性)。如果我们正在应用的更改是“删除”第一个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。