【发布时间】:2021-03-05 16:28:21
【问题描述】:
我正在编写一个 SQL 存储过程,它会为每个 AliasName 检索我在 NameAssociations 表中与之关联的 MasterNames,该表包含 AliasNameId、MasterNameId 和 MatchRank,以及StatusCode 列。我将使用存储过程在 C# 中对服务器端数据进行分页,所以我希望 startRow endRow 部分保持不变。
CREATE PROCEDURE [dbo].[NameAssociationsGetNameAssociations]
@StartRow INT = 1,
@EndRow INT = 1
AS
WITH result_set AS (
SELECT DENSE_RANK() OVER (ORDER BY an.Id) AS rowNum,
an.Id as AliasId, an.AliasName,
mn.Id as MasterId, mn.MasterName, mn.CodeId, mn.RowUpdateVersion AS ConcurrencyToken, na.MatchRank
FROM
NameAssociations na
INNER JOIN AliasNames an
ON na.AliasNameId = an.Id
INNER JOIN MasterNames mn
ON na.MasterNameId = mn.Id
WHERE
na.StatusCode = 0
)
SELECT
rowNum,
AliasId as Id, AliasName,
MasterId as Id, MasterName, CodeId, ConcurrencyToken, MatchRank
FROM
result_set
WHERE
rowNum BETWEEN @StartRow AND @EndRow
此过程有效并检索正确编号的行:
| rowNum | Id | AliasName | Id | MasterName | CodeId | ConcurrencyToken | MatchRank |
|---|---|---|---|---|---|---|---|
| 1 | 5 | BName | 34 | SomeName1 | 2 | 0x0000021 | 1 |
| 2 | 6 | DName | 21 | SomeName2 | 3 | 0x0000003 | 2 |
| 2 | 6 | DName | 2 | SomeName3 | 1 | 0x00000A2 | 1 |
| 2 | 6 | DName | 40 | SomeName4 | 1 | 0x00000B4 | 3 |
| 3 | 7 | AName | 11 | SomeName5 | 1 | 0x000005B | 1 |
所以基本上,对于每个AliasName,我都会得到一个MasterNames 的列表。
但是这些行没有按照我希望的方式排序,即AliasName ASC、Id(别名)ASC 和MatchRank ASC,看起来像这样:
| rowNum | Id | AliasName | Id | MasterName | CodeId | ConcurrencyToken | MatchRank |
|---|---|---|---|---|---|---|---|
| 1 | 7 | AName | 11 | SomeName5 | 1 | 0x000005B | 1 |
| 2 | 5 | BName | 34 | SomeName1 | 2 | 0x0000021 | 1 |
| 3 | 6 | DName | 2 | SomeName3 | 1 | 0x00000A2 | 1 |
| 3 | 6 | DName | 21 | SomeName2 | 3 | 0x0000003 | 2 |
| 3 | 6 | DName | 40 | SomeName4 | 1 | 0x00000B4 | 3 |
您可以看到别名的名称是按字母顺序排列的,然后关联的 master 被重新排序,所以 MatchRank 是按 ASC 顺序排列的。所有这一切,而 rowNum 是正确的,这是我一直难以实现的。
我尝试过PARTITION BY an.Id ORDER BY an.AliasName ASC, an.Id ASC, na.MatchRank ASC,但我一定误解了ORDER BY 在这种情况下的作用,因为结果错误。结果看起来它仅按MatchRank ASC 对记录进行排序并按它进行分区。我希望它按这三列对数据进行排序,然后按an.Id 对其进行分区。
如何编写查询以使输出结果看起来像表的第二个示例?我希望这一切都清楚了。
【问题讨论】:
-
PARTITION BY基本上是聚合的GROUP BY,因此每个新的Id都会重新编号。我想你想要ORDER BY AliasName, AliasId, MatchRank而没有PARTITION。实际输出行的顺序取决于您没有的外部ORDER BY,因此理论上这些行可能以与行编号结果不同的顺序返回。重新分页,你可能会觉得这很有趣:stackoverflow.com/a/66484823/14868997 -
您的查询和示例输出在逻辑上不匹配。
partition by an.id将为每个新的id值重新开始排名。我想你这里真的有order by? -
是的,这是一个
ORDER BY an.Id。
标签: sql sql-server