T-SQL排名w/第一、最小、最大、最后

T-SQL排名w/第一、最小、最大、最后,sql,sql-server,tsql,Sql,Sql Server,Tsql,嗨!我有一个SQL Server表,其中包含以下字段: DateTime DATETIME Price FLOAT 该表具有唯一的DateTime键。我想编写一个查询,返回20行块中的数据,返回每组20行的第一个、最大、最小和最后一个价格 非常感谢您在这方面提供的任何帮助……您是说: select *, (select Price from Prices where PurchaseDate = [Start]) as [First Price], (select P

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

DateTime DATETIME
Price FLOAT
该表具有唯一的DateTime键。我想编写一个查询,返回20行块中的数据,返回每组20行的第一个、最大、最小和最后一个价格


非常感谢您在这方面提供的任何帮助……

您是说:

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

你的意思是这样的:

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

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

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

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


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

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

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


您可以使用CTE的行数函数来完成此操作。以下是代码和详细信息:


您可以使用CTE的行数功能来完成此操作。以下是代码和详细信息:


20行基于什么标准-日期、价格或两者的某种组合?…用受保护关键字命名字段是个坏主意,即
DATETIME
。20行基于什么标准-日期、价格或两者的某种组合?…用受保护关键字命名字段是个坏主意,也就是说,
DATETIME
。感谢您的快速回答!!谢谢你的快速回答!!