我正在尝试检测数据库中的重复项。我想出一个我想做的MWE。并非每个id列都有一个值,但是id可能仍在文件名中。我正在尝试查找具有ID的所有行,该ID出现在不同行的文件名中。
这个查询是我要寻找的一种,但是问题是进行精确匹配
SELECT * FROM items WHERE id IN (
SELECT filename FROM items
);
IN运算符的缩写为:
name IN ("Bob Walters", "Alice Reed")
==> name == "Bob Walters" OR name = "Alice Reed"
但是我希望操作员执行此操作:
_________
==> "%" || name || "%" LIKE "Bob Walters" OR "%" || name || "%" LIKE "Alice Reed"
我正在寻找可以在空白处放入的内容以实现此操作。我的表只有10,000多行(因此,该解决方案不一定必须针对数百万行进行优化)。
答案 0 :(得分:2)
您想要的是EXISTS,而不是IN。试试:
SELECT *
FROM items AS i
WHERE EXISTS (SELECT *
FROM items AS i2
WHERE i.filename LIKE '%' || i2.id || '%' AND i.filename <> i2.filename)
答案 1 :(得分:1)
如果您使用的是SQLite 3+,则可以尝试使用REGEXP
运算符:
SELECT *
FROM items i1
WHERE EXISTS (SELECT 1 FROM items i2
WHERE i2.filename REGEXP '\b' || i1.id || '\b' AND
i1.id <> i2.id);
如果您的SQLite版本不支持REGEXP
,那么您可以 在其位置使用LIKE
>
SELECT *
FROM items i1
WHERE EXISTS (SELECT 1 FROM items i2
WHERE i2.filename LIKE '%' || i1.id || '%' AND
i1.id <> i2.id);
我在上面强调了 can ,因为LIKE
和通配符的问题在于它不仅会匹配完全匹配的内容,而且还会匹配子字符串,例如如果id=34983
在另一个记录中作为文件名中另一个ID的子字符串出现,则将出现误报。
答案 2 :(得分:0)
结合使用WHERE EXISTS
运算符和LIKE
运算符(在10,000个项目的数据库上大约50秒)
SELECT * FROM items AS i1 WHERE EXISTS (
SELECT * FROM items AS i2 WHERE i1.id != i2.id AND i2.filename LIKE '%' || i1.id || '%'
);
结合使用WHERE EXISTS
运算符和instr
函数(在10,000个项目的数据库上大约50秒)
SELECT * FROM items AS i1 WHERE EXISTS (
SELECT * FROM items AS i2 WHERE i1.id != i2.id AND instr(i2.filename, i1.id) != 0
);
结合使用WHERE EXISTS
运算符和LIKE
运算符,并仅查看具有空id的行(在10,000个项目的数据库中为30秒)
WHERE EXISTS
运算符和instr
函数,并仅查看具有空id的行(在10,000个项目的数据库中为30秒)<--
我使用的解决方案WHERE EXISTS
运算符与REGEXP
运算符结合使用WHERE EXISTS
运算符与MATCH
运算符(或另一个FTS4运算符)结合使用statement_id = 'SELECT * FROM items WHERE id IS NOT NULL and id != ""'
cursor.execute(statement_id)
ids = cursor.fetchall()
statement_title = 'SELECT * FROM items WHERE title IS NOT NULL AND title != ""'
cursor.execute(statement_title)
titles = cursor.fetchall()
matches = []
for id in ids:
for title in titles:
if id['id'] in title['title']:
matches.append([id, title])
总而言之,解决方案很丑陋,但我认为在这种情况下(这是一个个人项目,我不会经常进行这种重复数据删除操作,等等)。我认为全文扩展或重组数据库可能是更好的解决方案。