2016-07-30 178 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

哇,謝謝你的回答! –