我在长度为9的表中有数据,其中数据类似于
999999969
000000089
666666689
我想只删除那些1-9中任何数字重复超过5次的数据。
答案 0 :(得分:3)
好的,所以这里的逻辑可以概括为:
右?
所以,让我们把它分成一系列连续的数字:
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”。
后退引用( \ n )匹配前一个匹配的相同字符串 由数字
n
指定的带括号的子表达式[...]例如,([bc])\1
匹配bb
或cc
但不匹配bc
或cb
。