2013年7月4日星期四

UPDATE OPTIONS與LIKE一起REGEXP,SUBSTRING,和LOCATE

Original post: http://anothermysqldba.blogspot.com/2013/07/update-options-with-like-regexp.html

最近的一項的論壇的職位做了我停止,並覺得對於了片刻..
http://forums.mysql.com/read.php?10,589573,589573#MSG-589573

該的問題是,的用戶通緝,以更新只是的字的出租audi和而不是這個詞核數師。
它已於通過輕鬆地服用的本期間內的優勢,,一旦我停了下來試圖,以使用的,SUBSTRING和LOCATE解決。 ,他們想要一個快速和容易的的修正程式在的所有之後。


root@localhost [test]> CREATE TABLE `forumpost` (
-> `name` varchar(255) DEFAULT NULL
-> ) ENGINE=InnoDB;

root@localhost [test]> insert into forumpost value ('An auditor drives an audi.'),('An auditor drives a volvo.');

root@localhost [test]> select * from forumpost;
+----------------------------+
| name |
+----------------------------+
| An auditor drives an audi. |
| An auditor drives a volvo. |
+----------------------------+ 


所以現在就讓我們來更新它的快速和容易的的的的方式通過服用的本期間內的優勢,

root@localhost [test]>UPDATE forumpost SET name = REPLACE(name, 'audi.', 'toyota.') WHERE name LIKE '%audi.';
Query OK, 1 row affected (0.20 sec)
Rows matched: 1 Changed: 1 Warnings: 0

root@localhost [test]> select * from forumpost;
+------------------------------+
| name |
+------------------------------+
| An auditor drives an toyota. |
| An auditor drives a volvo. |
+------------------------------+ 


但是...... 什麼關於的有效的選項的SUBSTRING的和LOCATE .....


root@localhost [test]> insert into forumpost value ('An auditor drives an audi.');
root@localhost [test]> insert into forumpost value ('An auditor drives an audi car');
root@localhost [test]> select * from forumpost;
+-------------------------------+
| name |
+-------------------------------+
| An auditor drives an toyota. |
| An auditor drives a volvo. |
| An auditor drives an audi. |
| An auditor drives an audi car |
+-------------------------------+ 


首先測試您的的的,所以你使請務必你可以找到後,你是什麼東西的選項..


root@localhost [test]> SELECT * FROM forumpost WHERE name REGEXP 'audi car$';
+-------------------------------+
| name |
+-------------------------------+
| An auditor drives an audi car |
+-------------------------------+ 

root@localhost [test]> SELECT * FROM forumpost WHERE name LIKE '%audi car%';
+-------------------------------+
| name |
+-------------------------------+
| An auditor drives an audi car |
+-------------------------------+


那真的沒有做太多,自我們只是改變了本期間為的字車以來,。 因此,保持回事....

,我們需要,以拉只是這個詞的出租audi從該行與出租audi汽車。

root@localhost [test]> SELECT SUBSTRING(name,-8,4), name FROM forumpost WHERE SUBSTRING(name,-8,4) = 'audi';
+----------------------+-------------------------------+
| SUBSTRING(name,-8,4) | name |
+----------------------+-------------------------------+
| audi | An auditor drives an audi car |
+----------------------+-------------------------------+ 


的子串允許我到上拉的第一個的4個字符,後,我數了數回8個字符從的一端。

那麼,什麼如果你不知道的位置的字符,呢?
與你是否要啟動,應該檢討你的數據,以確保你知道你是什麼後,的。 但是,這些字符可能是圍繞您的的的字符串移動,所以讓我們與LOCATE的工作。

,我會添加另一行只是為的測試。

root@localhost [test]> insert into forumpost value ('An auditor drives an red audi car');
Query OK, 1 row affected (0.04 sec)

root@localhost [test]> select * from forumpost;
+------------------------------------+
| name |
+------------------------------------+
| An auditor drives an toyota. |
| An auditor drives a volvo. |
| An auditor drives an audi. |
| An auditor drives an audi car |
| An auditor drives an audi blue car |
| An auditor drives an red audi car |
+------------------------------------+ 


所以,不管,的的結局中,我們可以看到那個出租audi總是後,核數師,,所以我們只是需要跳過過度那個詞。 “核數師”這個詞是在第一的8個字符的,所以跳過的那些。

root@localhost [test]> SELECT LOCATE('audi', name,8), name FROM forumpost WHERE LOCATE('audi', name,8) > 0 ;
+------------------------+------------------------------------+
| LOCATE('audi', name,8) | name |
+------------------------+------------------------------------+
| 22 | An auditor drives an audi. |
| 22 | An auditor drives an audi car |
| 22 | An auditor drives an audi blue car |
| 26 | An auditor drives an red audi car |
+------------------------+------------------------------------+ 


OK(確定),所以,我們發現了的那些我們所後,的。 現在,,我們需要,,以寫的update語句。

,我們不能使用的replace此的時間。

UPDATE forumpost SET name = REPLACE(name, LOCATE('audi', name,8), 'mercedes') WHERE LOCATE('audi', name,8) > 0 ;
Query OK, 0 rows affected (0.02 sec)
Rows matched: 4 Changed: 0 Warnings: 0 

請注意它發現了的行,但沒有改變任何東西。

所以,再試一次,並我不希望,以承擔的位置8。 我想出租audi的第二個值的。
因此,一個測試顯示了,與SUBSTRING_INDEX,我可以跳過一日一,並用USE CONCAT

SELECT name , CONCAT ( SUBSTRING_INDEX(name, 'audi', 2) , ' mercedes ' , SUBSTRING_INDEX(name, 'audi', -1) ) as newvalue
FROM forumpost
WHERE LOCATE('audi', name,10) > 0 ;
+-----------------------------------+-----------------------------------------+
| name | newvalue |
+-----------------------------------+-----------------------------------------+
| An auditor drives an audi. | An auditor drives an mercedes . |
| An auditor drives an audi. | An auditor drives an mercedes . |
| An auditor drives an audi car | An auditor drives an mercedes car |
| An auditor drives an red audi car | An auditor drives an red mercedes car |
+-----------------------------------+-----------------------------------------+

root@localhost [test]> UPDATE forumpost SET name = CONCAT(SUBSTRING_INDEX(name, 'audi', 2) , ' mercedes ' , SUBSTRING_INDEX(name, 'audi', -1) )
WHERE LOCATE('audi', name,10) > 0 ;
Query OK, 4 rows affected (0.03 sec)
Rows matched: 4 Changed: 4 Warnings: 0

root@localhost [test]> select * from forumpost;
+-----------------------------------------+
| name |
+-----------------------------------------+
| An auditor drives an mercedes . |
| An auditor drives a volvo. |
| An auditor drives an mercedes . |
| An auditor drives an mercedes car |
| An auditor drives an red mercedes car |
+-----------------------------------------+
5 rows in set (0.00 sec) 


現在,授出一本語法,配合使用的“一個”是無效的的,但那是另一個故事。

上的這些可以的的更多信息,被在這裡找到: