具有First,Min,Max,Last的T-SQL排名

时间:2010-11-07 23:53:33

标签: sql sql-server tsql

HI!我有一个SQL Server表,其中包含以下字段:

DateTime DATETIME
Price FLOAT

该表具有唯一的DateTime键。我想写一个查询,以20行的方式返回数据,返回每组20行的FIRST,MAX,MIN和LAST价格。

在这方面的任何帮助都会受到高度赞赏......

3 个答案:

答案 0 :(得分:1)

我相信你的第一组只包含19行,而不是20行(因为行号从1开始,而不是0)。这很容易解决 - 只需从ROW_NUMBER()中减去1。

我还提供了一个替代解决方案,它可能会更加高效(因为它没有子查询可以作为嵌套循环实现),而且它也可能更易于管理。

注意:如果“价格”中的行数不能完全被20整除,则Sam和我的解决方案将返回一个少于20个项目的组的第一,最小,最大和最后价格 - 该组包含最近的项目。 (使用不能被20整除的行数来测试这样的查询是个好主意。)

DECLARE @groupsize INT = 20;
WITH PricesWithRkGp(PurchaseDate,Price,RkUp,RkDn,Gp) AS (
  SELECT
    PurchaseDate,
    Price,
    -1+ROW_NUMBER() OVER (ORDER BY PurchaseDate),
    -1+ROW_NUMBER() OVER (ORDER BY PurchaseDate DESC),
    (-1+ROW_NUMBER() OVER (ORDER BY PurchaseDate)) / @groupsize
  FROM Prices
)
  SELECT
    MIN(Price) AS MinPrice,
    MAX(Price) AS MaxPrice,
    Gp,
    MAX(CASE WHEN RkUp%@groupsize = 0 THEN Price ELSE NULL END) AS FirstPrice,
    MAX(CASE WHEN RkUp%@groupsize = @groupsize - 1 OR RkDn = 0 THEN Price ELSE NULL END) AS LastPrice
  FROM PricesWithRkGp
  GROUP BY Gp
  ORDER BY Gp;

答案 1 :(得分:0)

你的意思是这样的:

select 
    *,
    (select Price from Prices where PurchaseDate = [Start]) as [First Price],
    (select Price from Prices where PurchaseDate = [Finish]) as [Last Price]
from
(
    select 
        MIN(PurchaseDate) as [Start], 
        MAX(PurchaseDate) as [Finish], 
        MIN(Price) as [Min Price], 
        MAX(Price) as [Max Price], 
        AVG(Price) as [Average Price]
        from 
    (
        select (ROW_NUMBER() OVER (ORDER BY PurchaseDate)) / 20 as [Seq], *
        from Prices
    ) as X 
    group by X.Seq
) as Y

注意,我使用以下方法生成数据:

create table Prices (
PurchaseDate DATETIME primary key,
Price FLOAT
)

go

declare @records int
declare @date datetime 
declare @price float

set @records = 1000

while @records > 0 
begin 

    set @date = GETDATE() - cast((RAND() * 10000) as int)
    set @price = RAND() * 10000     

    if not exists(select 1 from Prices where PurchaseDate = @date) 
    begin 
        insert Prices values (@date, @price) 
        set @records = @records - 1
    end
end

答案 2 :(得分:0)

您可以使用CTE的ROW_NUMBER函数执行此操作。以下是包含详细信息的代码:

http://blog.sqlauthority.com/2007/06/11/sql-server-2005-t-sql-paging-query-technique-comparison-over-and-row_number-cte-vs-derived-table/

相关问题