Reputation: 5532
Consider a user enters a keyword to search for books. First the application searches by book title matches, if more than 50 books matches the search then it returns results; if not, it searches by book author matches. If together no more than 50 books matches, if then searches by book description matches.
Can SQL handle this situation? Or I have to write a stored procedure with ifs and elseifs?
[added] I use MySQL5.6. But I feel like the answer lies in in ANSI-SQL so I didn't specify it. Many thanks for your help!
Upvotes: 0
Views: 1173
Reputation: 3935
You can realize it using union all
with subqueries.
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
This works on SQL Server. On MySQL you need to use LIMIT
instead of TOP
.
You should specify which server you use in your tags.
EDIT (by other user):
This is an accepted answer, but it has a problem because it might return duplicates. A book that matches all three conditions can be returned three times. The union
doesn't eliminate them, because the rank
is different on each row.
One solution is to remove the rank and use a case
statement in the order by
:
order by (case when bookTitle = N'BLA' then 1
when bookAuthor = N'BLA' then 2
end)
EDIT by author: I changed the code above using the defined column names and a distinct, which will preserve duplicate entries.
Upvotes: 2
Reputation: 1269633
One approach to this is to do all the comparisons using a single query and then prioritize the results. The ANSI standard syntax would be like this:
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
Of course, the final clause is not supported in all databases, so it might be limit
or top
or something even worse.
If you have a large table, and performance is an issue, there are other ways to phrase the query, depending on what the matching conditions look like.
Upvotes: 3