sql - 如何从两个查询的联合中选择前n个,其中需要通过单个查询对结果顺序进行排名?

标签 sql tsql sql-server-2008 sql-server-2008-r2

假设我有一个包含用户名的表:

Id  |  Name
-----------
1   |  Bobby
20  |  Bob
90  |  Bob
100 |  Joe-Bob
630 |  Bobberino
820 |  Bob Junior


我想返回名称为“ Bob”的n匹配项列表,其中结果集首先包含完全匹配项,然后再包含类似的匹配项。

我以为这样的事情可能有用

SELECT TOP 4 a.* FROM
(
    SELECT * from Usernames WHERE Name = 'Bob'
    UNION
    SELECT * from Usernames WHERE Name LIKE '%Bob%'
) AS a


但是有两个问题:


这是一个低效的查询,因为子选择可能返回许多行(查看执行计划显示联接发生在top之前)
(几乎)更重要的是,由于结果集似乎按主键排序,因此精确匹配将不会首先出现在结果中。


我正在寻找将返回的查询(针对TOP 4)

Id | Name
---------
20 | Bob
90 | Bob

(and then 2 results from the LIKE query, e.g. 1 Bobby and 100 Joe-Bob)


在单个查询中有可能吗?

最佳答案

您可以使用case将完全匹配的内容放在顶部:

select  top 4 *
from    Usernames
where   Name like '%Bob%'
order by
        case when Name = 'Bob' then 1 else 2 end


或者,如果您担心性能并在(Name)上建立索引:

select  top 4 *
from    (
        select  1 as SortOrder
        ,       *
        from    Usernames
        where   Name = 'Bob'
        union all
        select  2
        ,       *
        from    Usernames
        where   Name like  '%Bob%'
                and Name <> 'Bob'
                and 4 >
                (
                select  count(*)
                from    Usernames
                where   Name = 'Bob'
                )
        ) as SubqueryAlias
order by
        SortOrder

关于sql - 如何从两个查询的联合中选择前n个,其中需要通过单个查询对结果顺序进行排名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6131323/

相关文章:

c# - 列出带有实例的可用 SQL Server 不包括 SQL Server Express

asp.net - 托管 ASP.NET 应用程序的硬盘空间对网站的性能有影响吗?

java - 如何在 hibernate 条件中使用日期部分

sql - 如何减慢 SQL 查询速度?

c# - SubmitChanges 立即取回记录

sql - 默认的 T-SQL JOIN 行为是什么,INNER 还是 OUTER?

sql-server - 序号从设定值开始

c# - 如何在不使用 asp.net 中的绑定(bind)和模板字段的情况下将数据表与 GridView 绑定(bind)?

sql - PostgreSQL:当前行为空时重复最后一行结果的查询

mysql - 从两个或多个表中查找唯一值