SQL:查找匹配但不完全匹配的行

时间:2016-07-30 21:42:37

标签: sql postgresql

我在PostgreSQL数据库中有一个表,其中包含列c1,c2 ... cn。我想运行一个查询,将每行与值v1,v2 ... vn的元组进行比较。查询不应返回完全匹配,但应返回以与值向量v递减相似的顺序排列的行列表。

示例:

该表包含体育记录:

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

现在,当我使用v =(Sweden,basketball,1998)对此表运行查询时,我希望获得与此向量具有相似性的所有记录,并按匹配列的数量按降序排序:

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

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

编辑:所有列都同样重要。虽然,当我真正想到它的时候......如果我能给每一列一个不同的权重因子,它将是一个不错的附加组件。

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

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

3 个答案:

答案 0 :(得分: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 + 

答案 1 :(得分:1)

这就是我要做的...在案例中使用的乘法因子将处理匹配的重要性(权重),并且它们将确保那些具有最高权重的列匹配的记录将会到来即使其他列不匹配这些特定记录,也要排在最前面。

/*
-- 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

答案 2 :(得分:0)

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