代码之家  ›  专栏  ›  技术社区  ›  Ivan

更正日期最低的唯一行的SQL语句

  •  0
  • Ivan  · 技术社区  · 7 年前

    我有一个SQL Server表,其中包含不同股票符号的每日数据时间序列。有些符号的数据比其他符号多,因为它们的时间序列开始或结束的日期不同于其他符号。

    我想从SQL Server数据库中获取所有符号的单行以及表中的第一个日期条目。我试过这个SQL语句

    sql = "SELECT date, symbol  
           FROM results_eod  
           WHERE date = (SELECT MIN(date) FROM results_eod s2 
                         WHERE symbol = s2.symbol)  
           ORDER BY symbol"
    

    但这将返回所有符号中最小日期相同的唯一行,例如 全部的 相同的 最小日期2008-1-1。如果开始日期不是2008-1-1,其他符号似乎被过滤掉了。

    正确的SQL是什么?

    3 回复  |  直到 7 年前
        1
  •  2
  •   MatBailie    7 年前

    你的WHERE条款错了。你需要…

    WHERE results_eod.symbol = s2.symbol
    

    如果有多个带有列的表 symbol 当前作用域中的表具有优先权。本质上,通过不在WHERE子句中指定表,您已经……

    WHERE s2.symbol = s2.symbol
    

    完全符合你的推荐信是值得的。不要懒惰,错过表名/别名。

        2
  •  1
  •   Traian GEICU    7 年前

    也试试这个。输出应包含所有符号,每个符号的日期最低,每个符号位于不同的行上。

    select symbol,min(date)
    from results_eod
    group by symbol
    order by date
    
        3
  •  0
  •   Gordon Linoff    7 年前

    当查询中引用了多个表时, 全部的 列应该是限定的(即具有表别名)。这个建议对于相关的子查询特别重要。

    所以:

    SELECT r.date, r.symbol 
    FROM results_eod r
    WHERE r.date = (SELECT MIN(r2.date)
                    FROM results_eod r2
                    WHERE r2.symbol = r.symbol
                   )  
    ORDER BY r.symbol;
    

    否则,引用——例如 symbol 子查询中的表可能不正确。

    索引打开时 results_eod(symbol, date) ,这可能是编写查询的最有效方法。然而,人们经常这样写:

    select r.*
    from (select r.*,
                 row_number() over (partition by r.symbol order by r.date) as seqnum
          from results_eod r
         ) r
    where seqnum = 1;