只使用Mysql替换替换中的所需匹配

时间:2016-05-05 23:30:32

标签: mysql replace

使用功能替换

src=LAYOUT_UNDEFINED

正常工作,直到字符串中有一个我不想替换的额外匹配。

在我的情况下,我有一个地址字段,我作为所有CAPS。但是,当它出现时,我想将'PR'改为'Prairie':

  • 'PR%'
  • '%PR'
  • %PR%'

但如果我这样做:

otherwise({
    redirectTo: $window.location.pathname === '/flight/' || '/air/' ? '/air' : '/hotel'
         });

然后if list2 == sorted(list2,key=lambda element:list1.index(element)): print('sorted') 变为Replace(FieldX,'FindString','ReplaceString') where FieldX = 'ABC'

我想,即使考虑到我的更改程度,我会在三个查询中解决这个问题,这很麻烦

Update TableA 
Set Address=Replace(Address,'PR','PRAIRIE')
where Address like '%PR ' or Address like 'PR %' or Address like '% PR '

但这将是繁琐的(我再做更多的替换和其他问题)并且似乎它仍然可能产生我没有预料到的错误。替换表也非常大,这使处理时间增加了三倍。

有没有人遇到解决这个问题的方法是不那么严厉的方法?如果这是正则表达式我可以逃脱它我想但我发现正则表达式为这种类型的替换添加了巨大的开销,正如我所说的表格很大。

2 个答案:

答案 0 :(得分:1)

你可以通过用两个空格包装所有内容然后替换它来完成这个(我认为)。 (如果使用正则表达式而不影响单词中的pr,则会处理^ PR和PR $情况,因为之前和之后永远不会有空格。使用trim作为删除空格的最后一步:

mysql> SELECT TRIM(REPLACE(' PR PRIMO ', ' PR ', ' PRAIRIE '));
+--------------------------------------------------+
| TRIM(REPLACE(' PR PRIMO ', ' PR ', ' PRAIRIE ')) |
+--------------------------------------------------+
| PRAIRIE PRIMO                                    |
+--------------------------------------------------+
1 row in set (0.00 sec)

请注意,如果在大型表上使用大量替换,使用表来协调更新应该可以节省大量时间。下面是一个示例,其中通过更新中的concat添加和删除空格,允许您只是将正常值添加到替换表。

代码:

DROP TABLE IF EXISTS hugeTable;
CREATE TABLE hugeTable(address CHAR(32));

DROP TABLE IF EXISTS replacements;
CREATE TABLE replacements(find CHAR(8), `replace` CHAR(8));

INSERT INTO hugeTable VALUES ('PR PRIMO');

INSERT INTO replacements VALUES ('PR', 'PRAIRIE');

SELECT * FROM hugeTable;

UPDATE hugeTable A, replacements B
SET A.address = TRIM(REPLACE(CONCAT(' ', A.address, ' '), CONCAT(' ', B.find, ' '), CONCAT(' ', B.`replace`, ' ')));

SELECT * FROM hugeTable;

查询:

mysql> CREATE TABLE hugeTable(address CHAR(32));
Query OK, 0 rows affected (0.10 sec)

mysql>
mysql> DROP TABLE IF EXISTS replacements;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE replacements(find CHAR(8), `replace` CHAR(8));
Query OK, 0 rows affected (0.02 sec)

mysql>
mysql> INSERT INTO hugeTable VALUES ('PR PRIMO');
Query OK, 1 row affected (0.04 sec)

mysql>
mysql> INSERT INTO replacements VALUES ('PR', 'PRAIRIE');
Query OK, 1 row affected (0.01 sec)

mysql>
mysql> SELECT * FROM hugeTable;
+----------+
| address  |
+----------+
| PR PRIMO |
+----------+
1 row in set (0.00 sec)

mysql>
mysql> UPDATE hugeTable A, replacements B
    -> SET A.address = TRIM(REPLACE(CONCAT(' ', A.address, ' '), CONCAT(' ', B.find, ' '), CONCAT(' ', B.`replace`, ' ')));
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>
mysql> SELECT * FROM hugeTable;
+---------------+
| address       |
+---------------+
| PRAIRIE PRIMO |
+---------------+
1 row in set (0.00 sec)

此致

詹姆斯

答案 1 :(得分:1)

虽然我接受了詹姆斯·斯科特的答案,这是一个很好的解决方案,但我确实做了一些改编,并且认为我已经包括在这里,因为他的解决方案是优雅的,并且通过一些调整使这次更新实际上成为可能。

回顾他的核心集是:

SET A.address = 
TRIM(REPLACE(CONCAT(' ', A.address, ' '), 
CONCAT(' ', B.find, ' '), 
CONCAT(' ', B.`replace`, ' ')));
  1. 我使用填充术语的核心概念,并在他建议的“Set”函数中查找/替换。
  2. 我没有将find / replace作为需要连接的第二个表(这意味着将300条记录连接到2600万条记录),而是创建了一个脚本(使用Excel)来查找/替换每个查询。 / p>

  3. 我添加了一个where子句来减少要检查的记录集,这对于2600万条记录至关重要(是的,我在查询w和w {o Where上测试过)。这是唯一可能的,因为添加了填充(concat),因为我现在可以使用%findterm%% findtermfindterm %的额外两遍进行一次单独填充,同时填充确保findterm是一个独立的词。

  4. 最后,因为findterms可以存储为大写(PL)或Proper(Pl),我安装了一个函数,我在这里找到不区分大小写的替换(Case Insensitive REPLACE for MySQL),这样我不必每次运行两次查询以适应每种情况。
  5. 示例查询看起来像这样

    SET address = 
    TRIM(REPLACE_ci(CONCAT(' ',address, ' '), 
    CONCAT(' ', 'PL', ' '), 
    CONCAT(' ', 'Place', ' '))) where address like '%PL%';
    

    更新运行的统计数据成功:

    • 300查找/替换条款/查询
    • 5表
    • 总计4200万条记录
    • 最大表2600万条记录
    • 最小的表1/2万条记录
    • 更新了350万条记录
    • 十个小时