Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用正则表达式识别现有数据的MySQL SELECT语句_Sql_Mysql - Fatal编程技术网

使用正则表达式识别现有数据的MySQL SELECT语句

使用正则表达式识别现有数据的MySQL SELECT语句,sql,mysql,Sql,Mysql,我的web应用程序解析上传文件中的数据,并将其插入数据库表中。由于输入数据(银行交易数据)的性质,从一个上传到另一个上传可能存在重复数据。目前,我正在使用效率极低的代码检查是否存在重复项,方法是将数据库中日期范围内的所有行加载到内存中,并对它们进行迭代,然后将每个行与上载的文件数据进行比较 不用说,随着数据集大小的增加,这可能会变得非常缓慢 因此,我希望用一个SQL查询(针对MySQL数据库)来代替它,该查询检查重复数据的存在,例如 SELECT count(*) FROM transactio

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

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

因此,我希望用一个SQL查询(针对MySQL数据库)来代替它,该查询检查重复数据的存在,例如

SELECT count(*) FROM transactions WHERE desc = ? AND dated_on = ? AND amount = ?
这很好,但我的现实情况有点复杂。输入数据中的事务描述有时可能包含错误的标点符号(例如,“BANK 12323 description”通常可以表示为“BANK.12323.description”),因此,在进行比较之前,我们现有的(内存中)匹配逻辑会对此描述执行一些清理

虽然这在内存中起作用,但我的问题是,是否可以在SQL语句中进行清理,以便将匹配逻辑移动到数据库中,例如:

SELECT count(*) FROM transactions WHERE CLEAN_ME(desc) = ? AND dated_on = ? AND amount = ?
其中CLEAN_ME是一个清除字段中错误数据的过程

显然,最干净(不是双关语!)的解决方案是将已经清理过的数据存储在数据库中(在同一列中,或在单独的列中),但在我诉诸于此之前,我想我应该尝试找出是否有更聪明的方法来解决这个问题


非常感谢

最干净的方法确实是确保数据库中只有正确的数据

在本例中,“BANK.12323.DESCRIPTION”将由以下人员返回:

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

但是,当表中有大量数据时,这可能会带来性能问题。

最简单的方法是在适当的列上添加一个唯一的索引并使用。我将进一步建议将文件转换成CSV,并充分利用MySQL的内置函数,这肯定比你自己编写的任何东西都要快——如果你认为你必须把数据拉进你自己的应用程序,而MySQL则把所有的东西都放在适当的位置。 这个清理可以在SQL语句中完成吗

是的,您可以在数据库层编写一个:

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
但是,在一个大表中,这将非常糟糕

显然,最干净(不是双关语!)的解决方案是将已经清理过的数据存储在数据库中(在同一列中,或在单独的列中),但在我诉诸于此之前,我想我应该尝试找出是否有更聪明的方法来解决这个问题

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


这样做,并向正在进行批量比较的列添加索引,以提高性能。如果desc/dated on/amount始终是唯一的数据类型实际上是固有的,那么在模式中通过将其设置为唯一索引约束来表示它。

另一种方法是:

  • 插入前请清除说明

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

  • 使用“replace”或“on replicate key”语法,这两种语法都更合适replace“在出现现有唯一密钥冲突时,实际使用更新的行替换数据库中的现有行,例如:

    替换为交易记录(描述、日期、金额)值(?、、?)

    “在重复键上”允许您指定在重复键错误时要更新的列:

    在交易记录中插入(说明,日期,金额)值(?,) 重复密钥集上的金额=金额

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

如果希望保留现有主键,还可以在这三列上创建一个唯一的unix


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

我认为应该使用“BANK[.]12323[.]description”,以尽可能避免误报。