4

次のツイートの表を検討してください

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'

ただし、2つの質問があります。

  1. 考えられるすべての「alcoainc」インスタンスをキャッチするためのより良い方法はありませんか?
  2. SQLで複数の置換のための一種の配列を書くことは可能ですか(SQLでは、PHP内からではありません)。ここ。つまり、SQLで次のようなものを定義し、SQLarray("alcoa inc" => "{COMPANY|AA}", "caterpillar" => "{COMPANY|CAT}", "apple inc" => "{COMPANY{AAPL}")でループして一括置換します。

あなたの助けはありがたいです:-)

4

3 に答える 3

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

このソリューションの唯一の欠点は、2つの会社の名前が同じツイートに表示される場合を処理できないことです。そのうちの1つだけが交換されます。

デモ:http ://www.sqlfiddle.com/#!2/8da9d / 2


編集:で指摘されて@Marioいるように、同じ文字列に複数のインスタンスがある場合、一致によって誤った置換が発生する可能性があります。たとえば、文字列を置換とともに使用するI have a redapple from appleと、2番目の文字列が一致をトリガーし、次にすべての一致を置換appleするため、文字列になります。テーブルから一致する文字列を読み取ることによって、この状況も処理する更新されたクエリがあります。I have a red{COMPANY|AAPL} from {COMPANY|AAPL}appleLIKEREPLACE

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

于 2012-04-23T19:37:48.050 に答える
1

考えられるすべての「alcoainc」インスタンスをキャッチするためのより良い方法はありませんか?

REGEX(正規表現)検索。詳細については、公式のmysqlREGEXドキュメントを参照してください。

SQLで複数の置換のための一種の配列を書くことは可能ですか(SQLでは、PHP内からではありません)。ここ。SQLでarray( "alcoa inc" => "{COMPANY | AA}"、 "caterpillar" => "{COMPANY | CAT}"、 "apple inc" => "{COMPANY {AAPL}")のようなものを定義することを意味します一括置換のためにSQLでループします。

はい、特定のテーブルを作成してキー->値ディクショナリを格納し、そこから値を取得できます。たとえば、次のようになります。

 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');

これは可能な方法を説明するための単なる例であり、要件と特定のコンテキストに合わせて調整する必要があります。

于 2012-04-23T19:40:41.600 に答える
0

これを行う1つの方法は、ストアドプロシージャを使用することです。

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}'
于 2012-04-23T19:44:45.973 に答える