考虑用户输入关键字来搜索书籍。首先,应用程序按照书籍标题匹配进行搜索,如果超过50本书符合搜索条件,则返回结果;如果不是,则按书籍作者匹配进行搜索。如果一起不超过50本书匹配,则通过书籍描述匹配搜索。优先搜索 - SQL
SQL可以处理这种情况吗?或者我必须用ifs和elseifs写一个存储过程?
[新增]我使用MySQL5.6。但我觉得答案在于ANSI-SQL,所以我没有指定它。非常感谢您的帮助!
考虑用户输入关键字来搜索书籍。首先,应用程序按照书籍标题匹配进行搜索,如果超过50本书符合搜索条件,则返回结果;如果不是,则按书籍作者匹配进行搜索。如果一起不超过50本书匹配,则通过书籍描述匹配搜索。优先搜索 - SQL
SQL可以处理这种情况吗?或者我必须用ifs和elseifs写一个存储过程?
[新增]我使用MySQL5.6。但我觉得答案在于ANSI-SQL,所以我没有指定它。非常感谢您的帮助!
你可以通过子查询使用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)
编辑: 我改变上述使用定义的列名和一个独特的代码,这将保留副本条目。
辉煌!非常感谢! – lonelyloner
如果没有'ORDER BY',那么* no *保证从'UNION'返回的前50行是(如果存在)50行符合'bookTitle'条件的行。 –
是的你的权利,我已经忘记在战斗的热度。 :-刚刚添加它的例子。 – Ionic
一种方法是使用单个查询进行所有比较,然后优先考虑结果。 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
当然,最后一句是不是在所有的数据库支持,所以它可能是limit
或top
什么更糟糕。
如果您有一个大表,并且性能是一个问题,还有其他方法可以对查询进行短语处理,具体取决于匹配条件的样子。
您正在使用哪些DBMS? Postgres的?甲骨文? –
我已经提供了一个答案,应该可以在大多数DBMS中进行一些更改。但请提供您的DBMS,因为它会有所帮助。 :-) – Ionic