2010-11-07 45 views
1

嗨!我有一个包含以下字段的SQL Server表:T-SQL排名带第一,最小,最大,最后一个

DateTime DATETIME 
Price FLOAT 

该表具有唯一的DateTime键。我想编写一个查询,以20行块的形式返回数据,返回每行20行的FIRST,MAX,MIN和LAST Price。

在这方面的任何帮助,将greately感激...

+0

20行基于什么标准 - 日期,价格,或两者的组合? – 2010-11-07 23:56:22

+2

...并且以受保护的关键字命名的字段,即'DATETIME',这是一个糟糕的主意。 – JNK 2010-11-08 00:32:07

回答

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; 
+0

感谢您的回复! – 2010-11-08 19:11:33

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 
相关问题