我一直在开发这个 django 应用程序。我们从加利福尼亚州机构提取了一大组表格,处理数据并重新发布。我一直在尝试做一些简单的事情,但是简单的实现真的很慢,我可能认为自己陷入了困境。这是其中一张表的一些内容。这样的表还有很多。
mysql> desc EXPN_CD;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| AGENT_NAMF | varchar(45) | NO | | NULL | |
| AGENT_NAML | varchar(200) | NO | | NULL | |
| AGENT_NAMS | varchar(10) | NO | | NULL | |
| AGENT_NAMT | varchar(10) | NO | | NULL | |
| AMEND_ID | int(11) | NO | MUL | NULL | |
| AMOUNT | decimal(14,2) | NO | | NULL | |
| BAKREF_TID | varchar(20) | NO | | NULL | |
| BAL_JURIS | varchar(40) | NO | | NULL | |
| BAL_NAME | varchar(200) | NO | | NULL | |
| BAL_NUM | varchar(7) | NO | | NULL | |
| CAND_NAMF | varchar(45) | NO | | NULL | |
| CAND_NAML | varchar(200) | NO | | NULL | |
| CAND_NAMS | varchar(10) | NO | | NULL | |
| CAND_NAMT | varchar(10) | NO | | NULL | |
| CMTE_ID | varchar(9) | NO | | NULL | |
| CUM_OTH | decimal(14,2) | YES | | NULL | |
| CUM_YTD | decimal(14,2) | YES | | NULL | |
| DIST_NO | varchar(3) | NO | | NULL | |
| ENTITY_CD | varchar(3) | NO | | NULL | |
| EXPN_CHKNO | varchar(20) | NO | | NULL | |
| EXPN_CODE | varchar(3) | NO | | NULL | |
| EXPN_DATE | date | YES | | NULL | |
| EXPN_DSCR | varchar(400) | NO | | NULL | |
| FILING_ID | int(11) | NO | MUL | NULL | |
...
我正在浏览所有这些表格。我取出每个名字、“CAND”(候选人)、“AGENT”等,并将每个引用放入一行:
mysql> desc calaccess_campaign_browser_name;
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ext_pk | int(11) | NO | MUL | NULL | |
| ext_table | varchar(255) | NO | | NULL | |
| ext_prefix | varchar(255) | NO | | NULL | |
| naml | varchar(255) | YES | | NULL | |
| namf | varchar(255) | YES | | NULL | |
| nams | varchar(255) | YES | | NULL | |
| namt | varchar(255) | YES | | NULL | |
| name | varchar(1023) | YES | | NULL | |
+-------------+---------------+------+-----+---------+----------------+
这些值永远不会为空,但许多(有时是绝大多数)都是空字符串。
我正在构建名称列。执行此操作的明显方法是:
concat(namt, ' ', namf, ' ', naml, ' ', nams)
但是,当其中 2 个或 3 个为空白时,会在字符串的开头或结尾处提供大量双空格和空格填充。
我做过的事情:
1) 使用 python 正则表达式查找并删除多余的空格。如果我有一个月左右的时间来运行它,这是可行的。
2) 按照上面的方法将名称放在一起,然后使用 SQL 查找并替换多余的空格。再说一次,需要很长时间。
问题之一是 Python 的 MySQL 库有一个专门为处理大型结果集而设置的游标。大型查询操作没有类似的情况。或者也许我看错了。
% pip freeze
...
MySQL-python==1.2.5c
...
3) 将名称提取到制表符分隔的文本文件中并进行修复,然后将文件加载到新表中。布莱赫。很多愚蠢的脚本。使用 sed 还是 awk?什么?
4) 我可以在 15 个不同的查询中执行 concat() 操作,并且为每个查询执行正确的 concat,这样名称中就不会出现多余的空格。我有:
- namt = null 且 namf = null 且 naml = null 且 nams != null(案例 0001)
- namt = null 且 namf = null 且 naml != null 且 nams = null(案例 0010)
- namt = null 且 namf = null 且 naml != null 且 nams != null(案例 0011)
- 等等,等等
这实际上就是我所选择的。运行时间不到一天。哇哦!
但是我也因为其他原因在做类似的事情,我到底想写多少次这样的代码?恶心!
一定有一种我没有看到的更聪明的方法来做到这一点。我在大约 2 打表中执行此操作,每个表中有 2 - 5 个名称,有时大约 15,000 行,有时大约 20,000,000 行。大多数 table 的数量在 300,000 到 750,000 之间。而且,天啊,我累了吗……
最佳答案
在 MySQL 中,我认为您正在寻找 concat_ws()
:
concat_ws(' ', nullif(namt, ''), nullif(namf, ''), nullif(naml, ''), nullif(nams, ''))
如果该值为空,nullif()
会将其转换为 NULL
。 concat_ws()
忽略 NULL
值,因此您不会得到重复的空格。
关于python - 合并 mysql 表中的字符串,无需额外空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30359495/