2012-04-23 105 views
4

考虑鸣叫大众替换字符串在MySQL

id tweet 
------------------------------------------------------ 
1 alcoa inc stock analysis 
2 bullrider has added alcoa inc to portfolio 
3 caterpillar annual results 
4 more at http://bit.ly/d3423 on caterpillar 
5 making apple inc profits 

的下表我想与指定的标签,以取代公司名称,具体如下:

id tweet 
------------------------------------------------------ 
1 {COMPANY|AA} stock analysis 
2 bullrider has added {COMPANY|AA} to portfolio 
3 {COMPANY|CAT} annual results 
4 more at http://bit.ly/d3423 on {COMPANY|CAT} 
5 making {COMPANY|AAPL} profits 

现在我有以下查询:

UPDATE 
    tweets 
SET 
    tweet = REPLACE(tweet, 'alcoa inc', '{COMPANY|AA}') 
WHERE 
    tweet LIKE '% alcoa inc %' 
OR 
    tweet LIKE 'alcoa inc %' 
OR 
    tweet LIKE '% alcoa inc' 

我有两个问题,虽然:

  1. 没有更好的方法来捕捉所有可能的“alcoa inc”实例吗?
  2. 是否有可能在SQL中编写一个用于多个替换的数组(在SQL中,而不是在PHP中)。这里。我的意思是在SQL中定义类似于array("alcoa inc" => "{COMPANY|AA}", "caterpillar" => "{COMPANY|CAT}", "apple inc" => "{COMPANY{AAPL}")的东西,并在SQL中循环以进行批量替换。

您的帮助表示赞赏:-)

+0

你为什么不只是使用'鸣叫LIKE“% alcoa inc%''? – Lamak 2012-04-23 19:29:38

+4

我猜想它是不匹配的,例如'balcoa inc'。 – mellamokb 2012-04-23 19:30:33

+0

究竟是什么mellamokb说 – Pr0no 2012-04-23 19:31:07

回答

3

你可以尝试在表中存储行情和公司的名单,并使用这样的查询:

select 
    case 
     when c.ticker is not null then 
      replace(t.tweet, c.name, 
        concat('{COMPANY|',c.ticker,'}')) 
     else t.tweet 
    end as tweet 
from 
    tweets t 
left join 
    company c 
     on 
      t.tweet like concat('% ', c.name, ' %') 
     or 
      t.tweet like concat(c.name, ' %') 
     or 
      t.tweet like concat('% ', c.name) 
group by 
    t.id 

唯一的缺点是该解决方案不会处理两个公司的名字出现在同一条推文中的情况。其中只有一个将被替换。

演示:http://www.sqlfiddle.com/#!2/8da9d/2


编辑:由于@Mario指出,这是可能的匹配会导致不正确的更换是否有相同的字符串的多个实例。例如,使用带有替换apple的字符串I have a redapple from apple将导致字符串I have a red{COMPANY|AAPL} from {COMPANY|AAPL},因为第二个apple触发LIKE匹配,则REPLACE将替换每个匹配。我有一个通过读取匹配的字符串了一个表,以及处理这种情况,以及更新的查询:

select 
    case 
     when p.ticker is not null then 
      replace(t.tweet, 
       replace(p.replacestr, '{0}', p.name), 
       replace(p.replacestr, '{0}', concat('{COMPANY|',p.ticker,'}'))) 
     else t.tweet 
    end as tweet 
from 
    tweets t 
left join 
    (select * from pattern,company) p 
     on t.tweet like replace(p.pattern, '{0}', p.name); 
group by 
    t.id 

哪里Pattern是这样定义的表:

CREATE TABLE Pattern 
    (pattern varchar(50), replacestr varchar(50)); 

INSERT INTO Pattern 
    (pattern, replacestr) 
VALUES 
    ('% {0} %', ' {0} '), 
    ('{0} %', '{0} '), 
    ('% {0}', ' {0}'); 

演示:http://www.sqlfiddle.com/#!2/c71d4/3

+0

但据我所知,这可以通过运行查询两次解决,不是吗? – Pr0no 2012-04-23 20:32:42

+0

从技术上讲,这将解决它。 – mellamokb 2012-04-23 21:28:31

1

没有更好的方法来捕捉所有可能的“alcoa inc”实例吗?

REGEX(Reqular Expression)搜索。请查看官方mysql REGEX文档了解更多信息。

是否有可能在SQL中为多个 替换(在SQL中,因此不在PHP中)编写一个数组的排序。这里。我的意思是在SQL中定义 ,如array(“alcoa inc”=>“{COMPANY | AA}”, “caterpillar”=>“{COMPANY | CAT}”,“apple inc”=>“{COMPANY {AAPL} “)和 在SQL中循环遍历以进行批量替换。

是的,你可以创建一个特定的表来存储键 - >值字典,然后从中获得价值,所以FO例如:

table : dictionary 
+----------+-----------------------+---------------+ 
| name  | pattern    | replacement | 
+----------+-----------------------+---------------+ 
|alcoa inc | [[:space:]]+alcoa inc |{COMPANY|AA} | 
|apple inc | apple inc.*   |{COMPANY{AAPL} | 

你还可以用像下面的查询更新,例如:

UPDATE tweets SET tweets = REPLACE(tweet, 'alcoa inc', '{COMPANY|AA}') 
WHERE tweet RLIKE (SELECT pattern FROM dictionary WHERE name = 'alcoa inc'); 

这只是为了说明一个可能的方法的例子,你必须调整它为您的要求和具体环境。这样做的

0

一种方法是用存储过程:

CREATE PROCEDURE UpdateTweetsWithCompany 
    @CompanyName varchar(255) = 'alcoa inc', 
    @ReplaceValue varchar(255) = '{COMPANY|AA}' 
AS 
BEGIN 
    UPDATE 
     tweets 
    SET 
     tweet = REPLACE(tweet, @CompanyName, @ReplaceValue) 
    WHERE 
     tweet LIKE '% ' + @CompanyName + ' %' 
    OR 
     tweet LIKE @CompanyName + ' %' 
    OR 
     tweet LIKE '% ' + @CompanyName 
END 

然后调用它,有点像这样:

EXEC UpdateTweetsWithCompany 'alcoa inc', '{COMPANY|AA}' 
+0

尽管如此,'REPLACE'仍然会将“balcoa inc''这样的字符串替换为”{b | COMPANY | AA}“。 – 2012-04-23 19:47:58

+0

它不应该是因为'WHERE..LIKE'中提供的过滤器# – mellamokb 2012-04-24 12:10:30

+2

@mellamokb'tweet'可能是''我有一个来自苹果的红苹果''并且'REPLACE'会改变所有的事件。 E,g:如果我们将“apple”改为“{COMPANY | AA}”,则结果为:''我有{COMPANY | AA}“的红色{COMPANY | AA}。尽管WHERE条款会找到“apple”。 – 2012-04-24 12:17:55