MySQL自定义编辑距离函数,比对两个没有关联的数据表

在处理数据的时候发现有两个数据表没有任何关联,唯一有联系的是两列看起来有些相似的数据,名字相似但是不一样,例如下面的课程名称和教材名称:

两列数据不相同但是相似,Mysql里面不存在这样的直接函数功能,所以没有办法去join,只能用where去连接两个表。

另外,看到其他博主都说Mysql有个自带的编辑距离函数,直接拿来用就可以,亲身试验了一下根本不行,MySQL不认识什么similarity函数,也不认识LEVENSHTEIN函数,所以没办法,要自己去定义才行,下面是可执行的代码。

自定义similarity函数和LEVENSHTEIN函数,然后调用两个函数,亲们可以直接拿走直接用。在代码中我标记了两条虚线,第一条虚线以上部分就是自定义函数,亲们可以拿走直接用,完全不用更改直接复制就好。第二条虚线上面那段代码的是用where去连接两个具有相似字段的表,需要注意的是两个表的数据量最好不要过千,不然会很慢。

如果有大佬有更好的模糊匹配的方法可以在评论区艾特我,欢迎指教。

#jcjb_62111
#jhkc_62102
#pksj_6251
#kcjbsj_6211

#自定义编辑距离函数1
$word = mysql_real_escape_string($word);
mysql_qery("SELECT `term` FROM `words` WHERE levenshtein('$word', `term`) BETWEEN 0 AND 4");


DELIMITER $$

CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
  RETURNS INT
  DETERMINISTIC
  BEGIN
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
    DECLARE s1_char CHAR;
    -- max strlen=255
    DECLARE cv0, cv1 VARBINARY(256);
    SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
    IF s1 = s2 THEN
      RETURN 0;
    ELSEIF s1_len = 0 THEN
      RETURN s2_len;
    ELSEIF s2_len = 0 THEN
      RETURN s1_len;
    ELSE
      WHILE j <= s2_len DO
        SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
      END WHILE;
      WHILE i <= s1_len DO
        SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
        WHILE j <= s2_len DO
          SET c = c + 1;
          IF s1_char = SUBSTRING(s2, j, 1) THEN 
            SET cost = 0; ELSE SET cost = 1;
          END IF;
          SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
          IF c > c_temp THEN SET c = c_temp; END IF;
            SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
            IF c > c_temp THEN 
              SET c = c_temp; 
            END IF;
            SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
        END WHILE;
        SET cv1 = cv0, i = i + 1;
      END WHILE;
    END IF;
    RETURN c;
  END;$$
#自定义编辑距离函数2
CREATE FUNCTION levenshtein_ratio( s1 VARCHAR(255), s2 VARCHAR(255) )
  RETURNS INT
  DETERMINISTIC
  BEGIN
    DECLARE s1_len, s2_len, max_len INT;
    SET s1_len = LENGTH(s1), s2_len = LENGTH(s2);
    IF s1_len > s2_len THEN 
      SET max_len = s1_len; 
    ELSE 
      SET max_len = s2_len; 
    END IF;
    RETURN ROUND((1 - LEVENSHTEIN(s1, s2) / max_len) * 100);
  END; $$


DELIMITER ;

DELIMITER $$
DELIMITER ;

#建立相似度函数
set global log_bin_trust_function_creators=TRUE;
CREATE FUNCTION similarity(str1 VARCHAR(255), str2 VARCHAR(255))
  RETURNS INT
  BEGIN
    DECLARE dist INT;
    SET dist = LEVENSHTEIN(str1, str2);
    RETURN (1 - (dist / GREATEST(LENGTH(str1), LENGTH(str2)))) * 100;
  END;
---------------------------------------------------------------1

#根据课程号配置课程名称
create table hjj_test1 as 
select a.kch,b.kc_name from jhkc_62102 a 
left join kcjbsj_6211 b on a.kch=b.kch;
#按照小分类建立教材基本数据
drop table hjj_test2;
create table hjj_test2 as 
select * from jcjb_62111 t  where  t.jcname like'%技术%' order by bc desc;
#寻找课程名称当中相同类别数据
drop table hjj_test1_2;
create table hjj_test1_2 as 
select * from hjj_test1 t where  t.kc_name like'%技术%' ;
#课程名称与教材名称进行比对
drop table hjj_test3;
create table hjj_test3 as 
select t.* ,b.jcname,b.cbh ,similarity(t.kc_name,b.jcname)is_same from hjj_test1_2 t ,hjj_test2 b ;
 ---------------------------------------------------------------2
#根据编辑距和表格内容离求与课程相似的教材名称  

select t.* from (
select t.* ,row_number() over(partition by t.kc_name order by t.kc_name desc) rn from (
select t.kc_name,t.jcname,t.cbh,max(t.is_same)max_value from (
select * from hjj_test3 t where  t.kc_name in ('计算机组网技术','工业网络与组态技术','路由与交换技术','汽车电子控制技术','传感器与智能检测技术',
'数控加工自动编程技术','汽车性能与使用技术','电力电子技术','汽车单片机技术','接触镜验配技术专项训练',
'网络安全技术','药物分析与检测技术','视觉康复训练技术','近视防控技术','智能网联汽车底盘线控技术',
'智能汽车ADAS技术','电工电子技术2','电工电子技术2','电气控制技术','微生物学与实验技术',
'低视力评估和康复技术','数字电子技术','药物制剂技术','眼镜维修检测技术专项训练',
'验光技术专项训练','药物分离与纯化技术','数控加工自动编程技术','网站前台美化技术',
'无线局域网技术')) t 
group by  t.kc_name,t.jcname
order by t.kc_name,t.is_same desc) t ) t where  t.rn=1
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
您可以使用MySQL的CREATE FUNCTION语句来创建一个自定义函数,然后在函数中使用税率表进行计算。具体步骤如下: 1. 创建税率表 您可以使用CREATE TABLE语句来创建一个税率表,例如: ```sql CREATE TABLE tax_rates ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, rate DECIMAL(5,2) NOT NULL, PRIMARY KEY (id) ); ``` 2. 插入税率数据 将不同税率的名称和值插入到税率表中,例如: ```sql INSERT INTO tax_rates (name, rate) VALUES ('基本税率', 0.1); INSERT INTO tax_rates (name, rate) VALUES ('附加税率', 0.05); ``` 3. 创建自定义函数 使用CREATE FUNCTION语句来创建一个自定义函数,例如: ```sql CREATE FUNCTION calculate_tax(price DECIMAL(10,2), rate_id INT) RETURNS DECIMAL(10,2) BEGIN DECLARE tax DECIMAL(10,2); SELECT rate INTO tax FROM tax_rates WHERE id = rate_id; RETURN price * tax; END; ``` 该函数接受两个参数:商品价格和税率ID。它首先从税率表中获取相应的税率值,然后计算税费并返回结果。 4. 使用自定义函数 您可以使用SELECT语句来调用自定义函数,例如: ```sql SELECT price, calculate_tax(price, 1) AS tax FROM products; ``` 该语句将从产品表中选择价格,并使用税率表中ID为1的税率计算税费。函数将返回税费值并将其命名为“tax”。 请注意,以上示例仅为演示目的,并不代表最佳做法或最完整的代码。实际情况下,您可能需要根据具体业务需求进行修改和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金哥的小超人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值