sql-server 如何使用主键按字段条件对SQL Server表条目进行排名

xa9qqrwz  于 2022-10-31  发布在  SQL Server
关注(0)|答案(3)|浏览(186)

我有一个使用SQL Server后端的Access数据库,并且我编写了一个查询,该查询按AgreementID列对Panels表中的条目进行排序,使用PanelID主键确定排序。
MS Access中的查询如下:

SELECT 
    X.AgreementID, X.PanelID, X.Panel_TypeID, 
    ((SELECT COUNT(*) 
      FROM Panels 
      WHERE (PanelID < X.PanelID) 
        AND (AgreementID = X.AgreementID);) + 1) AS Rank
FROM 
    Panels AS X
WHERE 
    (((X.AgreementID) IS NOT NULL))
ORDER BY 
    X.AgreementID, X.PanelID;

输出如下所示:

如您所见,与AgreementID相关的每个条目都根据其PanelID进行了排名。
我遇到的问题是有20k行,在Access中运行需要的时间太长,所以我希望在后端重新创建它,希望它比在前端使用链接表运行得更快。
SQL Server似乎不支持上面的方法,因此我需要一些指针来帮助我解决这个问题。

ndh0cuux

ndh0cuux1#

您可以在SQL Server中使用子查询。但是,还有更好的方法可以做到这一点。
可以使用行编号函数。

SELECT 
    p.AgreementID,
    p.PanelID,
    p.Panel_TypeID,
    ROW_NUMBER() OVER (PARTITION BY p.AgreementID ORDER BY p.PanelID) AS Rank
FROM 
    Panels p
WHERE 
    p.AgreementID IS NOT NULL
ORDER BY 
    p.AgreementID, 
    p.PanelID
;

这个方法的逻辑稍有不同,因为它只计算非空行。如果你想先计算所有行,那么你需要这样做:

SELECT 
    p.AgreementID,
    p.PanelID,
    p.Panel_TypeID,
    p.Rank
FROM (
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY p.AgreementID ORDER BY p.PanelID) AS Rank
    FROM
        Panels p
) p
WHERE 
    p.AgreementID IS NOT NULL
ORDER BY 
    p.AgreementID, 
    p.PanelID
;

为了有效执行这些查询,您将需要索引。
聚集索引

Panels (AgreementID, PanelID)

或具有包含列的非聚集索引

Panels (AgreementID, PanelID) INCLUDE (Panel_TypeID)
xwmevbvl

xwmevbvl2#

在SQL Server中运行这样一个简单的子查询应该可以很好地工作。假设后端表与Access表具有相同的架构,请尝试删除一些括号并运行相同的查询:

SELECT 
    X.AgreementID, 
    X.PanelID, 
    X.Panel_TypeID, 
    (
    SELECT 
        COUNT(*) 
    FROM 
        Panels 
    WHERE 
        PanelID < X.PanelID
        AND AgreementID = X.AgreementID
    ) + 1 AS Rank
FROM 
    Panels X
WHERE 
    X.AgreementID IS NOT NULL
ORDER BY 
    X.AgreementID, 
    X.PanelID
;
sd2nnvve

sd2nnvve3#

如果您不喜欢摆弄T-SQL和传递查询,可以使用我的RowNumber函数foundx 1 e0f1x。
然后,查询可以简化为:

SELECT 
    AgreementID, 
    PanelID, 
    Panel_TypeID, 
    RowNumber(CStr([PanelID]), CStr([AgreementID])) AS Rank
FROM 
    Panels
WHERE 
    AgreementID IS NOT NULL
ORDER BY 
    AgreementID, 
    PanelID

由于数据被缓存,它应该运行得相当快。

GitHub上的完整文档:是的。

相关问题