2015-06-18 116 views
0

考慮用戶輸入關鍵字來搜索書籍。首先,應用程序按照書籍標題匹配進行搜索,如果超過50本書符合搜索條件,則返回結果;如果不是,則按書籍作者匹配進行搜索。如果一起不超過50本書匹配,則通過書籍描述匹配搜索。優先搜索 - SQL

SQL可以處理這種情況嗎?或者我必須用ifs和elseifs寫一個存儲過程?

[新增]我使用MySQL5.6。但我覺得答案在於ANSI-SQL,所以我沒有指定它。非常感謝您的幫助!

+0

您正在使用哪些DBMS? Postgres的?甲骨文? –

+0

我已經提供了一個答案,應該可以在大多數DBMS中進行一些更改。但請提供您的DBMS,因爲它會有所幫助。 :-) – Ionic

回答

1

你可以通過子查詢使用union all來實現它。

SELECT DISTINCT TOP(50) bookname 
FROM (
    SELECT TOP(50) bookname, 1 as rank 
    FROM yourTable 
    WHERE bookTitle = N'BLA' 
    UNION 
    SELECT TOP(50) bookname, 2 as rank 
    FROM yourTable 
    WHERE bookAuthor = N'BLA' 
    UNION 
    SELECT TOP(50) bookname, 3 as rank 
    FROM yourTable 
    WHERE bookDescription = N'BLA' 
) as data 
ORDER BY rank 

這適用於SQL Server。在MySQL上,您需要使用LIMIT而不是TOP。 您應該指定您在標籤中使用的服務器。

EDIT(由其他用戶):

這是一個公認的答案,但它有一個問題,因爲它可能返回重複。一本符合所有三個條件的書可以返回三次。 union不會消除它們,因爲rank在每一行上都不相同。

一種解決方法是刪除等級和使用case聲明中order by:由作者

order by (case when bookTitle = N'BLA' then 1 
       when bookAuthor = N'BLA' then 2 
      end) 

編輯: 我改變上述使用定義的列名和一個獨特的代碼,這將保留副本條目。

+0

輝煌!非常感謝! – lonelyloner

+0

如果沒有'ORDER BY',那麼* no *保證從'UNION'返回的前50行是(如果存在)50行符合'bookTitle'條件的行。 –

+0

是的你的權利,我已經忘記在戰鬥的熱度。 :-剛剛添加它的例子。 – Ionic

3

一種方法是使用單個查詢進行所有比較,然後優先考慮結果。 ANSI標準語法會是這樣的:

select b.* 
from books b 
where Title . . . or 
     Author . . . or 
     Description . . . 
order by (case when Title . . . then 1 
       when Author . . . then 2 
       when Description . . then 3 
      end) 
fetch first 50 rows only 

當然,最後一句是不是在所有的數據庫支持,所以它可能是limittop什麼更糟糕。

如果您有一個大表,並且性能是一個問題,還有其他方法可以對查詢進行短語處理,具體取決於匹配條件的樣子。