Mon*_*RPG 17 sql-server sql-server-2014
假设我在表中有以下整数值
32
11
15
123
55
54
23
43
44
44
56
23
Run Code Online (Sandbox Code Playgroud)
好了,名单可以继续了;没关系。现在我想查询这个表,我想返回一定数量的closest records
. 假设我想将 10 个最接近的记录匹配返回到数字 32。我可以有效地实现这一目标吗?
它在 SQL Server 2014 中。
Mar*_*ith 22
假设该列被索引,以下应该是相当有效的。
两次查找 10 行,然后返回一种(最多)20 行。
WITH CTE
AS ((SELECT TOP 10 *
FROM YourTable
WHERE YourCol > 32
ORDER BY YourCol ASC)
UNION ALL
(SELECT TOP 10 *
FROM YourTable
WHERE YourCol <= 32
ORDER BY YourCol DESC))
SELECT TOP 10 *
FROM CTE
ORDER BY ABS(YourCol - 32) ASC
Run Code Online (Sandbox Code Playgroud)
(即可能类似于下面的内容)
或者另一种可能性(将排序的行数减少到最大 10)
WITH A
AS (SELECT TOP 10 *,
YourCol - 32 AS Diff
FROM YourTable
WHERE YourCol > 32
ORDER BY Diff ASC, YourCol ASC),
B
AS (SELECT TOP 10 *,
32 - YourCol AS Diff
FROM YourTable
WHERE YourCol <= 32
ORDER BY YourCol DESC),
AB
AS (SELECT *
FROM A
UNION ALL
SELECT *
FROM B)
SELECT TOP 10 *
FROM AB
ORDER BY Diff ASC
Run Code Online (Sandbox Code Playgroud)
注意:上面的执行计划是针对简单表定义的
CREATE TABLE [dbo].[YourTable](
[YourCol] [int] NOT NULL CONSTRAINT [SomeIndex] PRIMARY KEY CLUSTERED
)
Run Code Online (Sandbox Code Playgroud)
从技术上讲,底部分支上的 Sort 也不需要,因为它也是由 Diff 排序的,并且可以合并两个排序的结果。但我没能得到那个计划。
查询具有ORDER BY Diff ASC, YourCol ASC
而不仅仅是ORDER BY YourCol ASC
,因为那是最终消除计划顶部分支中的 Sort 的原因。我需要添加辅助列(即使它永远不会改变结果,因为YourCol
对于具有相同 Diff 的所有值都是相同的),因此它会通过合并连接(连接)而不添加排序。
SQL Server 似乎能够推断出 X 上按升序查找的索引将提供按 X + Y 排序的行,并且不需要排序。但它无法推断以降序遍历索引会以与 YX 相同的顺序(甚至只是一元减去 X)传送行。计划的两个分支都使用索引来避免排序,但是TOP 10
底部分支中的 则按顺序排序Diff
(即使它们已经按该顺序排列)以使它们按所需的合并顺序排列。
对于其他查询/表定义,仅使用一种分支来获取合并计划可能会更棘手或不可能 - 因为它依赖于查找 SQL Server 的排序表达式:
TOP
归档时间: |
|
查看次数: |
25571 次 |
最近记录: |