SQL Server - 如何将 RANK 函数插入到已按排名顺序排序的行中?

Posted

技术标签:

【中文标题】SQL Server - 如何将 RANK 函数插入到已按排名顺序排序的行中?【英文标题】:SQL Server - How would I insert a RANK function to rows that are already sorted in ranked order? 【发布时间】:2017-07-28 05:04:55 【问题描述】:

因此,显然,根据教授的说法,除了一列显示下面代码中显示的列的排名之外,我一切都正确。我在想,本质上,它只需要在自己的列中显示左侧的行号。以下是说明:

销售经理现在希望您创建一份报告,对她进行排名 产品的总销售额和总销量(每个将 成为自己的专栏)。创建一个存储过程,返回 以下列,但还添加了两个新的排名列。

产品名称 |订单数 |总销售额 |总销售额 数量

我知道它在作业描述中没有额外的列,但我想我需要它。这是我目前所拥有的:

USE OnlineStore
GO

CREATE PROC spManagerProductSalesCount
AS
BEGIN
SELECT 
    P.Name AS 'Product Name',
    Isnull(Count(DISTINCT O.OrderID), 0) AS 'Orders Count',
    Sum(Isnull(O.OrderTotal, 0)) AS 'Total Sales Value',
    Sum (Isnull(OI.OrderItemQuantity, 0)) AS 'Total Sales Quantity'
FROM 
    Product P
INNER JOIN 
    OrderItem OI ON P.ProductID = OI.ProductID
INNER JOIN 
    Orders O on O.OrderID = OI.OrderID
GROUP BY
    P.Name
ORDER BY
    'Total Sales Value' DESC, 'Total Sales Quantity' DESC
END

更新:它确实需要在存储过程中,并且可以/应该使用 CTE。我可以在 CTE 方面使用一些帮助。这些对我来说相当困难。

【问题讨论】:

【参考方案1】:

这只是存储过程的选择部分,但它应该告诉你该怎么做:

declare @products table
(
Name varchar(50),
id int
)
declare @orderitems table
(
id int,
orderid int,
productid int,
orderitemquantity int
)
declare @orders table
(
orderid int,
ordertotal decimal(18,2)
)

insert into @products VALUES ('apple', 1)
insert into @products VALUES ('orange', 2)
insert into @products VALUES ('pear', 3)
insert into @products VALUES ('melon', 4)

insert into @orders values(1, 19.0)
insert into @orders values(2, 25.5)
insert into @orders values(3, 9.5)
insert into @orders values(4, 13.5)
insert into @orders values(5, 8.5)

insert into @orderitems VALUES(1, 1, 1, 20)
insert into @orderitems VALUES(2, 1, 2, 10)
insert into @orderitems VALUES(3, 2, 3, 5)
insert into @orderitems VALUES(4, 2, 4, 4)
insert into @orderitems VALUES(5, 3, 1, 10)
insert into @orderitems VALUES(6, 3, 2, 5)
insert into @orderitems VALUES(7, 4, 3, 3)
insert into @orderitems VALUES(8, 4, 4, 2)
insert into @orderitems VALUES(9, 5, 1, 5)
insert into @orderitems VALUES(10, 5, 4, 2)

;WITH summary as 
(
    SELECT p.Name as ProductName, 
    COUNT(o.orderid) as 'Orders Count',
    ISNULL(Sum(o.ordertotal),0) AS 'Total Sales Value',
    ISNULL(Sum(oi.orderitemquantity),0) AS 'Total Sales Quantity'
    FROM @products p
    INNER JOIN @orderitems oi on oi.productid = p.id
    INNER JOIN @orders o on o.orderid = oi.orderid 
    GROUP BY p.Name
)

SELECT ProductName, [Orders Count], [Total Sales Value], [Total Sales Quantity], 
RANK() OVER (ORDER BY [Total Sales Value] DESC) AS ValueRanking,
RANK() OVER (ORDER BY [Total Sales Quantity] DESC) AS QuantityRanking FROM summary

请注意这里的一些事情。可以将此代码剪切并粘贴到 Management Studio 查询窗口中并照此运行。它从一些表声明和示例数据的插入开始。问一个问题时,如果你做这部分工作总是有用的;如果完成了最无聊的部分,人们更有可能回答!

COUNT() 不需要 ISNULL 保护;如果没有值,则返回 0。

给定最终数据,您会发现 ValueRanking 和 QuantityRankings 是不同的(为了说明这一点,我对数据进行了修改)。这意味着最终结果只能按其中之一排序(或者实际上按任何其他列 - 排序不依赖于排名)。

HTH

【讨论】:

以上是关于SQL Server - 如何将 RANK 函数插入到已按排名顺序排序的行中?的主要内容,如果未能解决你的问题,请参考以下文章

SQL SERVER 的窗体函数OVER的使用:row_number/rank/dense_rank

SQL SERVER 的窗体函数OVER的使用:row_number/rank/dense_rank

使用 SQL Server Rank 函数对行进行排名而不跳过排名号

创建“部分”窗口函数以更新 SQL Server 中的数据

SQL Server排名或排序的函数

MySQL实现SQL Server排名函数