删除编号重复超过5的记录

时间:2014-06-23 10:47:31

标签: sql regex database postgresql pattern-matching

我在长度为9的表中有数据,其中数据类似于

999999969
000000089
666666689

我想只删除那些1-9中任何数字重复超过5次的数据。

3 个答案:

答案 0 :(得分:3)

好的,所以这里的逻辑可以概括为:

  • 查找任意给定数字中相同连续数字的最长系列;和
  • 如果最长值>>则返回true 5位数

右?

所以,让我们把它分成一系列连续的数字:

regress=> SELECT regexp_matches('666666689', '(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)', 'g');
 regexp_matches 
----------------
 {6666666}
 {8}
 {9}
(3 rows)

然后过滤最长的时间:

regress=> 

SELECT x[1] 
FROM regexp_matches('6666666898', '(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)', 'g') x 
ORDER BY length(x[1]) DESC 
LIMIT 1;

    x    
---------
 6666666
(1 row)

......但实际上,我们并不关心这一点,只要有任何条目超过5位数,所以:

SELECT x[1] 
FROM regexp_matches('6666666898', '(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)', 'g') x 
WHERE length(x[1]) > 5;

可以用作EXISTS测试,例如

WITH blah(n) AS (VALUES('999999969'),('000000089'),('666666689'),('15552555'))
SELECT n
FROM blah
WHERE EXISTS (
    SELECT x[1] 
    FROM regexp_matches(n, '(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)', 'g') x 
    WHERE length(x[1]) > 5
)

实际上非常有效并返回正确的结果(总是很好)。但它可以通过以下方式简化:

WITH blah(n) AS (VALUES('999999969'),('000000089'),('666666689'),('15552555'))
SELECT n
FROM blah
WHERE EXISTS (
    SELECT x[1] 
    FROM regexp_matches(n, '(0{6}|1{6}|2{6}|3{6}|4{6}|5{6}|6{6}|7{6}|8{6}|9{6})', 'g') x;
)

您可以在WHERE中使用相同的DELETE子句。

答案 1 :(得分:2)

在表现方面可怕而且可怕,但它应该有效:

DELETE FROM YOURTABLE 
 WHERE YOURDATA LIKE '%111111%' 
    OR YOURDATA LIKE '%222222%' 
    OR YOURDATA LIKE '%333333%'
    OR YOURDATA LIKE '%444444%'
    OR YOURDATA LIKE '%555555%'
    OR YOURDATA LIKE '%666666%'
    OR YOURDATA LIKE '%777777%'
    OR YOURDATA LIKE '%888888%'
    OR YOURDATA LIKE '%999999%'

答案 2 :(得分:2)

使用back reference使用正则表达式可以更简单

DELETE FROM tbl
WHERE  col ~ '([1-9])\1{5}';

就是这样。

解释

([1-9]) ...一个数字从1到9的字符类,为后面的后引用括起来。
\1 ...返回对第一个(仅在这种情况下)带括号的子表达式的引用 {5} ..完全(另一个)5次,使其“超过5”。

Per documentation:

  

后退引用( \ n 匹配前一个匹配的相同字符串   由数字 n 指定的带括号的子表达式[...]例如,([bc])\1匹配bbcc但不匹配bccb

SQL Fiddle demo.