【发布时间】:2014-08-18 23:27:59
【问题描述】:
我有一张大桌子,我需要检查类似的行。我不需要所有列值都相同,只是相似。行不能是“遥远的”(由对其他表的查询确定),没有值可能相差太大(我已经针对这些条件进行了查询),并且大多数其他值必须相同。我必须预料到一些歧义,所以一两个不同的值不应该破坏“相似性”(好吧,我可以通过只接受“完全相等”的行来获得更好的性能,但这种简化可能会导致错误;我将这样做作为选项)。
我要解决这个问题的方法是通过 PL/pgSQL:创建一个 FOR LOOP 迭代先前查询的结果。对于每一列,我都有一个 IF 测试是否不同;如果是,我增加一个差异计数器并继续。在每个循环结束时,我将值与阈值进行比较,看看是否应该将行保持为“相似”。
与纯 SQL 查询或涉及一些 PL/pgSQL 函数的 SQL 查询相比,这种重 PL/pgSQL 的方法似乎很慢。如果我知道哪些行应该不同,则很容易测试除 X 等效行之外的所有行,但差异可能出现在大约 40 行中的任何一行。 有没有办法通过单个查询来解决这个问题?如果没有,有没有比检查所有行更快的方法?
编辑:我提到了一个表,实际上它是一组以 1:1 关系链接的六个表。我不想解释什么是什么,那是a different question。从一张桌子上推断出我的情况对我来说很容易。所以我简化了它(但没有过度简化它——它应该展示我在那里遇到的所有困难)并做了一个例子来展示我需要什么。 Null 和其他任何东西都应该算作“不同”。无需编写脚本来测试这一切 - 我只需要找出是否有可能以任何比我想象的更有效的方式进行。
重点是我不需要计算行数(像往常一样),只需要计算列数。
EDIT2:previous fiddle - 这不是那么短,所以我把它放在这里只是为了存档。
EDIT3:简化示例here - 只是 NOT NULL 整数,省略了预处理。当前数据状态:
select * from foo;
id | bar1 | bar2 | bar3 | bar4 | bar5
----+------+------+------+------+------
1 | 4 | 2 | 3 | 4 | 11
2 | 4 | 2 | 4 | 3 | 11
3 | 6 | 3 | 3 | 5 | 13
当我运行select similar_records( 1 ); 时,我应该只得到第 2 行(2 列具有不同的值;这是在限制范围内),而不是 3(4 个不同的值 - 最多在两个差异的限制之外)。
【问题讨论】:
-
请发布表的定义(如
create table)一些示例数据和预期输出。听起来您可能正在寻找类似 @987654328@ 的东西 -
粘贴表定义,粘贴你查询/查询
-
@a_horse_with_no_name:老实说,这不是一张表,而是六张1:1关系的表,而且SQL查询很大,肯定太大了,无法插入SO问题。我考虑了您的 SUM 建议一段时间,但我认为不是这样(但也许我只是误解了一些东西)。无论如何,我会尽快尝试编辑我的问题,提供一些指向 SQLFiddle 或类似内容的链接。
-
另一个编辑。第一小提琴不清楚;我希望现在很清楚。
-
你知道SSCCE的缩写吗? Short, Self Contained, Correct (Compilable), Example。我相信你现实生活中的任务很复杂,你必须考虑很多事情。但这与您的 question 几乎没有关系。将您的示例简化为您真正想问的事情,并消除所有其他干扰。
标签: sql postgresql plpgsql