SQL Server是否在不显示完整结果集的情况下获取排名?

SQL Server是否在不显示完整结果集的情况下获取排名?,sql,sql-server,ranking,Sql,Sql Server,Ranking,假设我有一个Customer表和一个Purchase表,Customer和Purchase之间有一对零或多的关系 我知道我可以使用SQL Server中的rank函数,例如,根据购买金额获得前10名客户。但我也希望获得整个系统中特定客户的排名,但不返回排名在该客户之前的整个客户数据集 我对SQL实体框架的错误有点生疏,哈哈,所以我无法为这个查询构建一个有效的语句。有人知道rank或其他函数是否可以做到这一点吗?您可以通过聚合查询做到这一点: select count(customerid) +

假设我有一个Customer表和一个Purchase表,Customer和Purchase之间有一对零或多的关系

我知道我可以使用SQL Server中的rank函数,例如,根据购买金额获得前10名客户。但我也希望获得整个系统中特定客户的排名,但不返回排名在该客户之前的整个客户数据集


我对SQL实体框架的错误有点生疏,哈哈,所以我无法为这个查询构建一个有效的语句。有人知道rank或其他函数是否可以做到这一点吗?

您可以通过聚合查询做到这一点:

select count(customerid) + 1
from t
where t.value < (select t2.value from t t2 where t2.customerid = @customerid);
请注意,这是专门进行排名的。对于稠密的_秩和行数,需要类似但不同的逻辑


此查询可以充分利用customerid、value和value、customerid上的索引。

您可以通过聚合查询执行此操作:

select count(customerid) + 1
from t
where t.value < (select t2.value from t t2 where t2.customerid = @customerid);
请注意,这是专门进行排名的。对于稠密的_秩和行数,需要类似但不同的逻辑


此查询可以充分利用customerid、value和value、customerid上的索引。

这听起来像是一个很好的CTE候选项,并使用了您提到的窗口函数。您可以声明特定客户,使用CTE获取所有客户的购买金额,使用第二个CTE对所有客户进行排名,然后查询前10名并合并特定客户信息。如果第11人已经进入前10名,工会将淘汰他们。UNIONALL将给您一个重复的记录,但提供11行

DECLARE @userID INT = xxxx

;WITH cte1 AS (
SELECT 
customerID
, SUM(purchase_dollars) AS purchase_amount
FROM customer_table

GROUP BY customerID)

, cte_rank AS (
SELECT 
customerID
, RANK() OVER(ORDER BY purchase_amount DESC) AS purchase_amount_rank
--, ROW_NUMBER() OVER(ORDER BY purchase_amount DESC) AS purchase_amount_rank --This will get you 10 records
FROM cte1)

SELECT 
t1.CustomerID
, t2.purchase_amount_rank

FROM customer_table t1
INNER JOIN cte_rank t2
ON t1.customerid = t2.customerid
WHERE t2.purchase_amount_rank <= 10

UNION 

SELECT t1.customerID
, t2.purchase_amount_rank
FROM customer_table t1
INNER JOIN cte_rank t2
ON t1.customerid = t2.customerid
AND t1.customer_id = @userID

ORDER BY t2.purchase_amount_rank

这听起来像是CTE的一个很好的候选者,并且使用了您提到的窗口功能。您可以声明特定客户,使用CTE获取所有客户的购买金额,使用第二个CTE对所有客户进行排名,然后查询前10名并合并特定客户信息。如果第11人已经进入前10名,工会将淘汰他们。UNIONALL将给您一个重复的记录,但提供11行

DECLARE @userID INT = xxxx

;WITH cte1 AS (
SELECT 
customerID
, SUM(purchase_dollars) AS purchase_amount
FROM customer_table

GROUP BY customerID)

, cte_rank AS (
SELECT 
customerID
, RANK() OVER(ORDER BY purchase_amount DESC) AS purchase_amount_rank
--, ROW_NUMBER() OVER(ORDER BY purchase_amount DESC) AS purchase_amount_rank --This will get you 10 records
FROM cte1)

SELECT 
t1.CustomerID
, t2.purchase_amount_rank

FROM customer_table t1
INNER JOIN cte_rank t2
ON t1.customerid = t2.customerid
WHERE t2.purchase_amount_rank <= 10

UNION 

SELECT t1.customerID
, t2.purchase_amount_rank
FROM customer_table t1
INNER JOIN cte_rank t2
ON t1.customerid = t2.customerid
AND t1.customer_id = @userID

ORDER BY t2.purchase_amount_rank

你能澄清一下吗?您希望根据购买金额获得前10名客户,但在整个系统中,其他排名值将基于什么?请告诉我们您希望结果集是什么样子。假设您是一个正在查看排行榜的用户。排行榜将显示前10名,但如果你是500岁,你就不会进入前10名。因此,用户界面将显示11条记录…前10条记录,最后一条记录将显示500条记录,其中包含您的信息。您能澄清一下吗?您希望根据购买金额获得前10名客户,但在整个系统中,其他排名值将基于什么?请告诉我们您希望结果集是什么样子。假设您是一个正在查看排行榜的用户。排行榜将显示前10名,但如果你是500岁,你就不会进入前10名。因此,用户界面将显示11条记录……前10条记录,最后一条记录将显示500条记录,其中包含您的信息。值得注意的是,如果这些记录的购买金额相同,则可能会显示数千条记录。如果每个人的购买金额相同,则排名/密集排名将为他们分配相同的排名。我将在代码中散列一个行号以适应这种情况。值得注意的是,如果它们都有相同的购买金额,这可能会得到数千条记录。如果每个人的购买金额相同,则排名/密集排名将为他们分配相同的排名。我将在代码中散列一个行号以适应这一点。