我怎样才能在GROUP BY中获得TOP?

时间:2015-11-12 14:45:58

标签: sql-server

var initVal = @Html.Raw(HttpUtility.HtmlEncode(@Model.ReferralHistoryDetail[1].ReferralComments).Replace("\n", "<br />"))

我想通过符号获取最后的TargetPosition - 我该怎么做?

OrderUTC                Symbol  TargetPosition  
2011-02-01 3:59:59.000  GBPUSD  1000000 
2011-02-01 13:59:59.000 GBPUSD  1000000 
2011-02-01 5:59:59.000  EURUSD  1000000 
2011-02-01 22:59:59.000 EURUSD  1000000

不起作用

  

专栏&#39; FX.dbo.Orders.TargetPosition&#39;在选择列表中无效   因为它不包含在聚合函数或   GROUP BY子句。

5 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是使用row_number,然后仅使用数字1,如下所示:

select Symbol,TargetPosition from (
  SELECT Symbol,TargetPosition,
    row_number() over (partition by Symbol order by OrderUTC) as RN
  FROM [FX].[dbo].[Orders]
) X
where RN = 1

答案 1 :(得分:1)

使用窗口功能代替单独订购每个符号的定价。

<execution>
<phase>initialize</phase>
 <goals>
   <goal>set-system-properties</goal>
 </goals>

答案 2 :(得分:0)

你马上遇到了几个问题。首先,TOP限制返回的记录数,它不关心值。第二个GROUP意味着聚合函数将应用于所有使用的非分组列(TargetPosition和OrderUTC)。

现在,要做你想做的事情,已经有一些答案可行,所以我会给你一些不同的东西。

SELECT
  Symbol,
  FIRST_VALUE(TargetPosition) OVER (PARTITION BY Symbol ORDER BY OrderUTC DESC)
FROM
  FX.dbo.Orders
GROUP BY
  Symbol

答案 3 :(得分:0)

我认为与总行数相比,不同符号的数量非常少。我不会使用聚合,而是使用APPLY。这将只为每个符号寻找一个。

我会创建一个包含所有可能符号的表(GBPUSD,EURUSD ......)。我们称之为SymbolTable,试试这个:

WITH Symbols AS
(
  SELECT Symbol
  FROM SymbolTable
)
SELECT S.Symbol, A1.TargetPosition
FROM Symbols AS S
CROSS APPLY (SELECT TOP (1) O.TargetPosition
             FROM [FX].[dbo].[Orders] AS O
             WHERE O.Symbol = S.Symbol
             ORDER BY OrderUTC DESC
            ) AS A1;

但你需要一个索引(符号ASC,OrderUTC DESC,INCLUDE TargetPosition)。如果有许多不同的符号,使用窗口函数将比此解决方案表现更好。

答案 4 :(得分:0)

使用Over Partition by symbol是一个更好的解决方案。但是,对于不熟悉分析函数的人来说,这可能更容易理解。

在分析之前,在CTE之前,这是实现预期结果的常用方法。

获取一组由每个符号的最大日期组成的数据,然后将结果连接回基本集以消除非当前符号并获得具有最大日期的目标位置。

因此,使用基于集合的处理,我们有一组符号及其连接的最大日期,这些符号将设置回整个集合,以消除那些没有最大日期的符号,而这些符号将保留最大日期的符号和targetPosition。

SELECT A.Symbol, A.TargetPosition
FROM ORDERS A
INNER JOIN (SELECT max(OrderUTC) mDate, symbol 
  FROM orders
  GROUP BY Symbol) B
 on B.mDate = A.orderUTC
and B.Symbol = A.Symbol