2016-07-30 113 views
5

我在PostgreSQL数据库中有一个表,其中列c1,c2 ... cn。我想运行一个查询,将每行与值为v1,v2 ... vn的元组进行比较。查询不应该返回精确匹配,但应该返回降序相似值矢量V下令行的列表SQL:查找紧密匹配但不完全匹配的行

例:

表中包含运动记录:

1,USA,basketball,1956 
2,Sweden,basketball,1998 
3,Sweden,skating,1998 
4,Switzerland,golf,2001 

现在,当我对v =(瑞典,篮球,1998)对该表进行查询,我想获得与此矢量相似的所有记录,按照匹配列数从大到小的顺序排列:

2,Sweden,basketball,1998 --> 3 columns match 
3,Sweden,skating,1998 --> 2 columns match 
1,USA,basketball,1956 --> 1 column matches 

行4不返回,因为它根本不匹配。

编辑:所有列同样重要。虽然,当我真的想到它的时候......如果我可以给每个列赋予不同的权重因子,这将是一个很好的附加组件。

是否有任何可能的SQL查询会在合理的时间内返回行,甚至当我对一百万行运行它时?

这样的查询会是什么样子?

+1

好问题恕我直言 – objectNotFound

+1

问题:每列在排列匹配行时有相同的权重吗? – objectNotFound

+0

objectNotFound,感谢您的问题,请参阅我对权重的编辑。 –

回答

2
SELECT * FROM countries 

WHERE country = 'sweden' 
OR sport = 'basketball' 
OR year = 1998 

ORDER BY 
cast(country = 'sweden' AS integer) + 
cast(sport = 'basketball' as integer) + 
cast(year = 1998 as integer) DESC 

这不是很美,但很好。您可以将布尔表达式转换为整数并对它们进行求和。

您可以通过添加乘数器轻松更改重量。

cast(sport = 'basketball' as integer) * 5 + 
0

如果您编写了一个存储过程来计算两行之间的“相似性度量”,这可能会有帮助。然后,您的查询可以直接引用该过程的返回值,而不是在where-expression和order-by-expression中具有许多条件。

+0

有趣!这个存储过程是什么样的? –

1

这就是我应该如何做的......在这种情况下使用的乘法因子stmts将处理匹配的重要性(重量),并且他们将确保那些匹配最高权重列的匹配记录即使其他列与特定记录不匹配,也会出现顶部。

/* 
-- Initial Setup 

-- drop table sport 
create table sport (id int, Country varchar(20) , sport varchar(20) , yr int) 

insert into sport values 
(1,'USA','basketball','1956'), 
(2,'Sweden','basketball','1998'), 
(3,'Sweden','skating','1998'), 
(4,'Switzerland','golf','2001') 

select * from sport 
*/ 


select * , 
     CASE WHEN Country='sweden'  then 1 else 0 end * 100 + 
     CASE WHEN sport='basketball' then 1 else 0 end * 10 + 
     CASE WHEN yr=1998    then 1 else 0 end * 1  as Match 
from sport 
WHERE 
    country = 'sweden' 
OR sport = 'basketball' 
OR yr  = 1998 
ORDER BY Match Desc 
+0

哇,谢谢你的回答! –