1

我有两张表,一张包含关键字,另一张包含字符串值。我想添加一个列,其中将插入对第一个表 id 的引用。这个插入的值将基于第一行的字符串将被提取,并且将检查它是否包含来自另一个表的任何关键字,如果在字符串中找到关键字,则在此处插入该关键字的 id (应该包含外键约束)。

我对如何实现这一点感到困惑。应该是一个过程或触发器,因为这个字段应该在插入后填充。我正在尝试触发器,但无法计算出字符串函数。

我是 SQL 和学习新手,所以尝试了 INSTR() 但它只需要第一个关键字。

此外,由于两个表每个都包含大约 10000 个值,因此哪种方式最好且最快。

一张桌子是运动包含

id - sport

其他表是包含

id - countryid - tag - link - email - sportid

funlocater中的数据是手动填充的,除了应该自动填充的sportid部分。

例如。定位器中的一行包含

1 - 183 - skatebording competition at tawar mall - www.abcd.com/abcd?xyz - abcd@abcd.com - ???

现在,如果包含在 funlocater 的标签列字符串中,则在检查关键字滑板之后,运动 ID 应该包含运动表中的运动 ID。

这就像INSTR('skateboarding', funlocater.tag) 但我想检查所有最匹配的值。我如何进行匹配工作?INSTR()做这项工作,但只取一个值。我想检查是否找到关键字然后插入sports.id 或检查下一个关键字。

4

1 回答 1

1

首先,我想说你最好规范化你的数据库模式并将你的映射存储在一个像这样的表中

CREATE TABLE funlocater_sports 
(
    funlocater_id INT NOT NULL, 
    sports_id INT NOT NULL,
    PRIMARY KEY pk_funlocater_sports(funlocater_id, sports_id),
    FOREIGN KEY fk_funlocater(funlocater_id) REFERENCES funlocater(id),
    FOREIGN KEY fk_sports(sports_id) REFERENCES sports(id)
);

不过,您可以通过这样的查询来实现您的直接目标

UPDATE funlocater l JOIN
(
  SELECT f.id, GROUP_CONCAT(s.id) sport_ids
    FROM funlocater f JOIN sports s
      ON FIND_IN_SET(s.sport, REPLACE(f.tag, ' ', ',')) > 0
   GROUP BY f.id
) q ON l.id = q.id
   SET l.sportid = q.sport_ids

这样,您将从sports表格sportid列中的funlocater表格中获得逗号分隔的运动 ID 列表。

这是SQLFiddle演示

如果您想使用触发器,那么最好在这样的函数中分解出通用代码

CREATE FUNCTION tag_to_sportid(atag VARCHAR(512))
RETURNS VARCHAR(512) 
DETERMINISTIC
RETURN
  (
      SELECT GROUP_CONCAT(s.id)
        FROM (SELECT 1 id) f JOIN sports s
          ON FIND_IN_SET(s.sport, REPLACE(atag, ' ', ',')) > 0
       GROUP BY f.id
  );

然后触发

CREATE TRIGGER tg_funlocator_insert
BEFORE INSERT ON funlocater
FOR EACH ROW
  SET NEW.sportid = tag_to_sportid(NEW.tag);

CREATE TRIGGER tg_funlocator_update
BEFORE UPDATE ON funlocater
FOR EACH ROW
  SET NEW.sportid = tag_to_sportid(NEW.tag);

这是SQLFiddle演示

于 2013-06-11T08:40:38.087 回答