如何在最小/最大上进行自连接

发布于 2025-01-02 01:52:10 字数 1331 浏览 7 评论 0原文

我是 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

I am new to sql queries.
Table is defined as

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

I need to find for each symbol in a given date range, max(high) and min(low) and corresponding dates for max(high) and min(low).

  • Okay to get first max date and min date in given table.
  • In a given date range some dates may be missing. If start date is not present then next date should be used and if last date is not present then earlier available date should be used

Data is for one year and around 5000 symbols.

I tried something like this

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

誰認得朕 2025-01-09 01:52:10

第一个 INNER 查询预先限定每个交易品种在所提供的日期范围内的低值和高值。之后,它再次连接回原始表(对于相同的日期范围条件),但还添加了低值或高值与 PreQuery 中的 MIN() 或 MAX() 匹配的限定符。如果是这样,则允许它出现在结果集中。

现在,结果列。不知道您使用的是哪个版本的 SQL,我将前 3 列作为“最终”值。接下来的 3 列来自通过任一限定符限定的记录。由于股票一直在上涨和下跌,因此在同一时间段内高值和/或低值可能会多次出现。这将包括符合 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 )

The first INNER query pre-qualifies for each symbol what the low and high values are within the date range provided. After that, it joins back to the original table again (for same date range criteria), but also adds the qualifier that EITHER the low OR the high matches the MIN() or MAX() from the PreQuery. If so, allows it in the result set.

Now, the result columns. Not knowing which version SQL you were using, I have the first 3 columns as the "Final" values. The following 3 columns after that come from the record that qualified by EITHER of the qualifiers. As stocks go up and down all the time, its possible for the high and/or low values to occur more than once within the same time period. This will include ALL those entries that qualify the MIN() / MAX() criteria.

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 )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文