【问题标题】:How to correct a set of values in a column using REGEXP by removing spaces in MySQL?如何通过删除 MySQL 中的空格来使用 REGEXP 更正列中的一组值?
【发布时间】:2020-02-07 19:39:26
【问题描述】:

我正在寻求一些帮助,以清理我表中的参考编号列表。正确的参考编号由 8 个或 13 个数字组成,因此我一直在查看数据表中的不同模式,以找出需要修复的错误。以下是我遇到的错误示例,我正在寻找建议以采用最佳实践而不是重复编码。

以下是我的创建表和插入语句以及我想要的输出。

创建表

CREATE TABLE “BU_REF_NO" 
   (           "REF_NO" VARCHAR2(255 BYTE)
   );

插入语句

INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('12 103 501');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('10 1234 5678 901');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('12 3456 7890 123');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('123456 7890 123');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('987654 3210 321');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('12345678 1234567890123');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('1234567890123 12345678');
INSERT INTO "BU_REF_NO" (REF_NO) VALUES ('1234567890 123');

最终输出

REF_NO
12103501
1012345678901
1234567890123
1234567890123
9876543210321
12345678 1234567890123
1234567890123 12345678
1234567890123

我的查询选择以数字开头的行序列,在 2 个字符之后有一个空格。

SELECT
    *
FROM
    BU_REF_NO
WHERE
    REF_NO REGEXP '^[0-9]{2} '
    ;

这给了我以下输出:

REF_NO
12 103 501
10 1234 5678 901
12 3456 7890 123

现在我陷入困境的是尝试正确的方法来删除所有不同序列的空格,即 2 个字符然后一个空格,或 6 个字符和一个空格。我正在考虑为我表中的序列运行以下代码,但我确信有一种更简单的方法可以实现这一点,因此寻求一些建议。

我目前拥有的是以下(尚未测试):

UPDATE BU_REF_NO SET REF_NO = '' WHERE REF_NO REGEXP '^[0-9]{2} ';
UPDATE BU_REF_NO SET REF_NO = '' WHERE REF_NO REGEXP '^[0-9]{6} ';
UPDATE BU_REF_NO SET REF_NO = '' WHERE REF_NO REGEXP '^[0-9]{10} ';

我可能需要包括的另一件事是检查不包括空格的值的总数,因为我只需要在我总共有 8 个或 13 个值时运行一些代码,所以这可能需要包含在我的代码开头。最后,如果我的值少于 8 个或多于 13 个,则 REF_NO 将保持原样。

提前致谢。


更新:

您好,感谢大家的回复。为了从示例数据中清楚起见,我展示了哪些列应该被修改,哪些列保持不变(BU_REF_NO_AMENDED 不是一个存在的列,只是在代码之后显示它应该是什么样子):

BU_REF_NO | BU_REF_NO_AMENDED
12 103 501 | 12103501
10 1234 5678 901 | 1012345678901
12 3456 7890 123 | 1234567890123
123456 7890 123 | 1234567890123
987654 3210 321 | 9876543210321
12345678 1234567890123 | 12345678 1234567890123
1234567890123 12345678 | 1234567890123 12345678
1234567890 123 | 1234567890123

因此,修改后的列中的所有行都删除了除 2 之外的空格 (BU_REF_AMENDED)(12345678 1234567890123、1234567890123 12345678)。原因是因为这两行有 8 位,一个空格,然后是 13 位或 13 位,一个空格,然后是 8 位。

没有修改这两行的原因是因为这些行具有正确的 ref_numbers,我需要保持这些行不变。

希望能澄清我的最终输出。


您好,我已经编写了以下查询来计算我想要的行中数字的长度,因为我认为这可能有助于我编写一个内部查询来仅选择需要删除空格以使其更容易的行.

SELECT
  REF_NO, 
  LENGTH(REF_NO) AS LENGTH_WITH_SPACE,
  LENGTH(REF_NO) - LENGTH(REPLACE(REF_NO, ' ', '')) AS SPACES,
  LENGTH(REF_NO) - (LENGTH(REF_NO) - LENGTH(REPLACE(REF_NO, ' ', ''))) AS LENGTH_WITHOUT_SPACES
FROM
  BU_REF_NO

;

这给了我输出:

REF_NO | LENGTH_WITH_SPACE | SPACES | LENGTH_WITHOUT_SPACES
12 103 501 | 10 | 2 | 8
10 1234 5678 901 | 16 | 3 | 13
12 3456 7890 123 | 16 | 3 | 13
123456 7890 123 | 15 | 2 | 13
987654 3210 321 | 15 | 2 | 13
12345678 1234567890123 | 22 | 1 | 21
1234567890123 12345678 | 22 | 1 | 21
1234567890 123 | 14 | 1 | 13 

现在我正在考虑编写一个外部查询,该查询将为所有等于 13 的值以及 SPACES 列中空格大于 1 的值选择 LENGTH_WITHOUT_SPACES 列。然后我可以运行 REGEXP REPLACE 查询来替换空格。

将尝试并发布我的结果。

这是我尝试过的,它有效!

SELECT
  REF_NO,
  CASE
    WHEN LENGTH_WITHOUT_SPACES = 8 AND SPACES > 0 THEN REGEXP_REPLACE(REF_NO,' ','') 
    WHEN LENGTH_WITHOUT_SPACES = 13 AND SPACES > 0 THEN REGEXP_REPLACE(REF_NO,' ','')
    ELSE REF_NO 
  END AS REF_AMENDED
FROM
  (
SELECT
  REF_NO, 
  LENGTH(REF_NO) AS LENGTH_WITH_SPACE,
  LENGTH(REF_NO) - LENGTH(REPLACE(REF_NO, ' ', '')) AS SPACES,
  LENGTH(REF_NO) - (LENGTH(REF_NO) - LENGTH(REPLACE(REF_NO, ' ', ''))) AS LENGTH_WITHOUT_SPACES
FROM
  BU_REF_NO
;

只需要更新现有列即可。

【问题讨论】:

  • 我很困惑。 1234567890 123不应该变成1234567890123吗?
  • 仅供参考,SET REF_NO = '' 会将 ref_no 设置为空字符串,这样你的日子就会不好过。
  • 您是要清理这些数字中的空格还是删除整个条目?
  • 谢谢 MonkeyZeus,输入错误,1234567890 123 应该是 1234567890123,我已经在上面的代码中编辑了这个。
  • 我正在尝试清理空格而不是删除条目,不会删除参考编号,只是删除空格给我准确的参考编号。

标签: mysql regex


【解决方案1】:

看看一个简单的替换是否足够,你的例子有缺陷。

CREATE TABLE BU_REF_NO 
   (           END_DATE VARCHAR(255)
   );
INSERT INTO BU_REF_NO (END_DATE) VALUES ('12 103 501');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('10 1234 5678 901');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('12 3456 7890 123');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('123456 7890 123');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('987654 3210 321');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('12345678 1234567890123');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('1234567890123 12345678');
INSERT INTO BU_REF_NO (END_DATE) VALUES ('1234567890 123');
✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
UPDATE BU_REF_NO SET END_DATE = REPLACE(END_DATE,' ','');
SELECT * FROM BU_REF_NO;
| END_DATE | | :-------------------- | | 12103501 | | 1012345678901 | | 1234567890123 | | 1234567890123 | | 9876543210321 | | 123456781234567890123 | | 123456789012312345678 | | 1234567890123 |

db小提琴here

【讨论】:

  • 感谢 nbk 的回复。问题不是替换 REF_NO 列中的所有空格,就好像我有一个 REF_NO 有 13 位数字和一个空格,然后是 8 位数字(如果它的 8 位数字、空格、13 位数字相同),那么我不想要从该行中删除空间,因此我认为使用 REGEXP 可以帮助我将这些空间分开。
  • 获取您提供的数据并写下所有行的实际结果,您的输出建议了我的答案。
【解决方案2】:

没有量词的正则表达式“^[0-9]+”就足够了

【讨论】:

    猜你喜欢
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 2022-12-22
    • 2022-12-17
    • 2020-06-25
    相关资源
    最近更新 更多