代码之家  ›  专栏  ›  技术社区  ›  Olly

MySQL SELECT语句使用Regex识别现有数据

  •  1
  • Olly  · 技术社区  · 17 年前

    我的web应用程序解析上传文件中的数据,并将其插入数据库表中。由于输入数据(银行交易数据)的性质,从一个上传到另一个上传可能会存在重复数据。目前,我正在使用效率极低的代码来检查是否存在重复项,方法是将数据库中日期范围内的所有行加载到内存中,并对其进行迭代,然后将每个行与上传的文件数据进行比较。

    不用说,随着数据集大小的增加,这可能会变得非常缓慢。

    SELECT count(*) FROM transactions WHERE desc = ? AND dated_on = ? AND amount = ?
    

    这很好,但我的真实案例有点复杂。输入数据中的交易描述有时可能包含错误的标点符号(例如,“BANK 12323 description”通常可以表示为“BANK.12323.DESCRIPTING”),因此我们现有的(内存中的)匹配逻辑在进行比较之前会对该描述进行一些清理。

    虽然这在内存中有效,但我的问题是,这种清理是否可以在SQL语句中完成,这样我就可以将这种匹配逻辑移动到数据库中,比如:

    SELECT count(*) FROM transactions WHERE CLEAN_ME(desc) = ? AND dated_on = ? AND amount = ?
    

    显然,最干净(无意双关!)的解决方案是存储 数据库中的数据(可以在同一列中,也可以在单独的列中),但在我采取行动之前,我想我会尝试找出是否有更聪明的方法来解决这个问题。

    4 回复  |  直到 17 年前
        1
  •  1
  •   bobince    17 年前

    是的,你可以写一个 stored procedure

    mysql> CREATE FUNCTION clean_me (s VARCHAR(255))
        -> RETURNS VARCHAR(255) DETERMINISTIC
        -> RETURN REPLACE(s, '.', ' ');
    
    mysql> SELECT clean_me('BANK.12323.DESCRIPTION');
    
    BANK 12323 DESCRIPTION
    

    不,就数据库而言,最干净的方式总是最聪明的方式(只要性能不差)。

        2
  •  1
  •   soulmerge    17 年前
        3
  •  0
  •   tehvan    17 年前

    SELECT count(*) FROM transactions
    WHERE desc LIKE 'BANK%12323%DESCRIPTION' AND dated_on = ? AND amount = ?
    

        4
  •  0
  •   jonstjohn    17 年前

    • 插入前请清除描述。

    • 为表创建一个主键,该主键是唯一标识条目的列的组合。听起来可能是清洁描述、日期和金额。

    • 插入交易(desc、dated_on、amount)值(?、?、?)

    通过使用多列主键,您将获得很多性能,因为主键查找通常非常快。

    无论你选择哪种方式,我都建议在进入数据库之前清理描述,即使你也存储了原始描述,只使用清理后的描述进行索引。