0

我正在创建一个交易平台,我需要从一个表中获取以下数据:

date, open price, close price, highest price, lowest price, volume, value of volume.

我创建了这个查询:

Select 
    min(Price) as Low,
    max(price) as High,
    sum(Quantity) as Volume,
    sum(Price) as Value,
    dateadd(DAY, 0, datediff(day, 0, CreatedOn)) as Date,
    CompanyIdentifier 
from 
    Transactions 
group by 
    dateadd(DAY, 0, datediff(day, 0, CreatedOn)), CompanyIdentifier

这个查询是为某家公司(由 标识CompanyIdentifier)在某天(Date)带来最低价、最高价、成交量和成交量价值。我不能在此查询中添加的是开盘价和收盘价那天该公司的价格。基本上是数据按日期升序排列的前 1 个价格。我尝试过并且似乎可以解决问题的是以下查询:

SELECT * 
FROM (select Quantity, PRICE, CompanyIdentifier, 
             dateadd(DAY,0, datediff(day,0, CreatedOn)) AS U, 
             ROW_NUMBER() over(partition by CompanyIdentifier, dateadd(DAY,0, datediff(day,0, CreatedOn)) order by CREATEDON) AS 'COUN' 
      from Transactions
     ) AS AL 
where COUN = 1

但这些是 2 个单独的查询,我只想要一个查询。我还尝试添加:

FIRST_VALUE(Price) over (order by price) as first

在第一个查询中,但我收到该函数不在 group by 子句中的错误,我将函数添加到 group by 查询中,我收到以下错误:

窗口函数只能出现在 SELECT 或 ORDER BY 子句中。

那么,如何在第一个查询中添加这两列?

4

2 回答 2

1

一种方法是使用窗口函数和select distinct

select distinct t.CompanyIdentifier, v.createdDate,
       min(Price) over (partition by t.CompanyIdentifier, v.createdDate) as Low,
       max(price) over (partition by t.CompanyIdentifier, v.createdDate) as High,
       sum(Quantity) over (partition by t.CompanyIdentifier, v.createdDate) as Volume,
       sum(Price) over (partition by t.CompanyIdentifier, v.createdDate) as Value,
       first_value(Price) over (partition by t.CompanyIdentifier, v.createdDate order by CreatedOn asc) as first_price,   
       first_value(Price) over (partition by t.CompanyIdentifier, v.createdDate order by CreatedOn desc) as last_price   
from Transactions t cross apply
     (values (convert(date, CreatedOn))) v(createdDate)

这是必需的,因为 SQL Serverfirst_value()作为窗口函数提供,但与聚合函数没有任何相似之处。

更传统的方法使用条件聚合:

Select t.CompanyIdentifier, t.createdDate,
       min(Price) as Low, max(price) as High,
       sum(Quantity) as Volume, sum(Price) as Value,
       min(case when seqnum_asc = 1 then price end) as first_price,
       min(case when seqnum_desc = 1 then price end) as last_price
from (select t.*,
             createdDate,
             row_number() over (partition by CompanyIdentifier, createdDate order by CreatedOn) as seqnum_asc,
             row_number() over (partition by CompanyIdentifier, createdDate order by CreatedOn desc) as seqnum_desc
      from Transactions t cross apply
           (values (convert(date, CreatedOn))) v(createdDate)
     ) t
group by t.CompanyIdentifier, v.createdDate;
于 2020-04-12T12:07:18.140 回答
0

FIRST_VALUE() OVER是一个分析函数,根据我的经验,它们与 GROUP BY 子句不太吻合。

一个简单的解决方法应该是将使用分析函数的子查询加入FIRST_VALUE到您的表中,并且收盘价LAST_VALUE可以解决问题。

Select 
min(Price) as Low,
max(price) as High,
sum(Quantity) as Volume,
sum(Price) as Value,
dateadd(DAY, 0, datediff(day, 0, CreatedOn)) as Date,
analytic.first,
analytic.close
CompanyIdentifier 
from 
Transactions,
(SELECT CompanyIdentifier, FIRST_VALUE(price) OVER (CreatedOn) as first, LAST_VALUE(price) OVER (CreatedOn) as close) as analytic
where
Transactions.CompanyIdentifier = analytic.CompanyIdentifier 
group by 
dateadd(DAY, 0, datediff(day, 0, CreatedOn)), CompanyIdentifier,analytic.first,analytic.close

我希望它对您有用,也许需要对查询进行一些调整,因为我根据您的示例使用了假设。

于 2020-04-12T12:08:55.823 回答