如何在最小/最大值上进行自我加入

时间:2012-02-04 17:01:12

标签: sql inner-join self minmax

我是sql查询的新手。 表定义为

(  symbol varchar,
   high int,
   low int,
   today date,
   Primary key (symbol, today)
)

我需要查找给定日期范围内的每个符号,max(high)min(low)以及max(high)min(low)的相应日期。

  • 可以在给定的表格中获得第一个最大日期和最小日期。
  • 在给定的日期范围内,某些日期可能会丢失。如果不存在开始日期,则应使用下一个日期,如果不存在最后日期,则应使用较早的可用日期

数据为一年,大约5000个符号。

我试过这样的事情

SELECT a.symbol,
       a.maxValue,
       a.maxdate,
       b.minValue,
       b.mindate
FROM (
    SELECT table1.symbol, max_a.maxValue, max_a.maxdate
    FROM table1
    INNER JOIN (
        SELECT table1.symbol,                            
               max(table1.high) AS maxValue, 
               table1.TODAY AS maxdate
        FROM table1
        GROUP BY table1.symbol
    ) AS max_a  
    ON max_a.symbol = table1.symbol
    AND table1.today = max_a.maxdate
) AS a  
INNER JOIN (
    SELECT symbol,
           min_b.minValue,
           min_b.mindate 
    FROM table1
    INNER JOIN (
        SELECT symbol,
               min(low) AS minValue, 
               table1.TODAY AS mindate
        FROM table1
        GROUP BY testnsebav.symbol
    ) AS min_b
    ON min_b.symbol = table1.symbol
    AND table1.today = min_b.mindate
) AS b
ON a.symbol = b.symbol

1 个答案:

答案 0 :(得分:0)

第一个INNER查询为每个符号预先限定了低值和高值在所提供的日期范围内的值。之后,它再次连接回原始表(对于相同的日期范围标准),但也添加了低于或高的高级匹配符合来自PreQuery的MIN()或MAX()的限定符。如果是这样,请在结果集中允许它。

现在,结果列。不知道您使用的是哪个版本的SQL,我将前3列作为“最终”值。之后的3列来自由限定符的EITHER限定的记录。随着股票一直上涨和下跌,高和/或低价值可能在同一时期内出现不止一次。这将包括符合MIN()/ MAX()标准的所有条目。

select
      PreQuery.Symbol,
      PreQuery.LowForSymbol,
      PreQuery.HighForSymbol,
      tFinal.Today as DateOfMatch,
      tFinal.Low as DateMatchLow,
      tFinal.High as DateMatchHigh
   from
      ( select
              t1.symbol,
              min( t1.low ) as LowForSymbol,
              max( t1.high ) as HighForSymbol
           from 
              table1 t1
           where
              t1.today between YourFromDateParameter and YourToDateParameter
           group by
             t1.symbol ) PreQuery
      JOIN table1 tFinal
         on PreQuery.Symbol = tFinal.Symbol
        AND tFinal.today between YourFromDateParameter and YourToDateParameter
        AND (   tFinal.Low = LowForSymbol
             OR tFinal.High = HighForSymbol )