【问题标题】:SQL getting averages with multiple joinsSQL 获取多个连接的平均值
【发布时间】:2015-10-23 13:57:45
【问题描述】:

我正在尝试使用 3 个表编写一个查询。
我将使用的表格及其列是:

Sec – ID, Symbol
Hss – Code, HDate, Holiday
Fddd – ID, Date, Price

给定一个符号AAA,我需要从第一个表中获取 ID 并将其与第三个表中的 ID 匹配。第二个表的日期必须与第三个表的日期匹配,条件为Code=1Holiday=1

第二个和第三个表格中的日期按升序排列,最近的日期在底部。我想得到50 day200 day 的平均价格。表格中的日期按升序排列,因此我想将其降序并选择top 50200 以获得平均价格。

到目前为止,我只能得到一个平均值。我无法添加第二个SELECT TOP 50 或在第二个avg() 中添加subquery

SELECT AVG(TwoHun)TwoHunAvg   --, AVG(Fifty) AS FiftyAvg 
FROM (SELECT TOP 200 Fddd.price AS TwoHun    --, TOP 50 Fddd.price AS Fifty
FROM Sec 
JOIN Fddd
ON Sec.ID = Fddd.ID AND Sec.symbol = 'AAA' 
JOIN Hss 
ON Fddd.date = Hss.Hdate AND Hss.Code = 1 AND Hss.Holiday = 1 
ORDER BY Fddd.Date DESC) AS tmp;

提前致谢!

【问题讨论】:

  • 您可能需要提及您正在使用的数据库。
  • 拥有样本数据以便能够进行测试也将有所帮助!您的问题也有点混乱,请提供 2 个表格。一种是数据,另一种是您想要的结果。
  • @mustaccio 我认为是 ms 访问或 SQL 服务器。参考:w3schools.com/sql/sql_top.asp

标签: sql tsql join


【解决方案1】:

考虑一个联合查询,它甚至可以扩展到其他平均值。我添加了一个类型列来指示平均值。

SELECT '200 DAY AVG' As Type, AVG(TwoHun) As Avg
FROM 
  (SELECT TOP 200 Fddd.price AS TwoHun
   FROM Sec 
   INNER JOIN Fddd ON Sec.ID = Fddd.ID 
   INNER JOIN Hss ON Fddd.date = Hss.Hdate
   WHERE Sec.symbol = 'AAA' AND Hss.Code = 1 AND Hss.Holiday = 1 
   ORDER BY Fddd.Date DESC) AS tmp;

UNION

SELECT '50 DAY AVG' As Type, AVG(FiftyHun) As Avg
FROM 
  (SELECT TOP 50 Fddd.price AS FiftyHun
   FROM Sec 
   INNER JOIN Fddd ON Sec.ID = Fddd.ID
   INNER JOIN Hss ON Fddd.date = Hss.Hdate
   WHERE Sec.symbol = 'AAA' AND Hss.Code = 1 AND Hss.Holiday = 1 
   ORDER BY Fddd.Date DESC) AS tmp;

另外,我将您的一些连接表达式移到了 where 子句中,该子句不会改变性能,但会提高可读性。

【讨论】:

  • 这并不是用户所要求的,因为您在两个不同的行中提供值,而它们被请求为两个不同的列。
  • 正确,因此是“考虑”。你打败了我最初的要求。我提供了 OP 的替代方案,也许还有未来的读者。并且可以为 Avgs 数据集添加 100 天、30 天、15 天。另外,还有四重子查询与双子查询的性能方面......
【解决方案2】:

我怀疑您使用的是 SQL Server 或 MS Access。

一种快速的解决方案是将您的总查询作为子查询,然后复制修改后的版本作为第二个子查询。

快速粗略的例子:

    SELECT (SELECT
         AVG(Fifty) AS FiftyAvg
       FROM (SELECT TOP 50
         Fddd.price AS Fifty
       FROM Sec
       JOIN Fddd
         ON Sec.ID = Fddd.ID
         AND Sec.symbol = 'AAA'
       JOIN Hss
         ON Fddd.date = Hss.Hdate
         AND Hss.Code = 1
         AND Hss.Holiday = 1
       ORDER BY Fddd.Date DESC) AS tmp)
       AS FiftyAvg,
       (SELECT
         AVG(TwoHun) TwoHunAvg
       FROM (SELECT TOP 200
         Fddd.price AS TwoHun
       FROM Sec
       JOIN Fddd
         ON Sec.ID = Fddd.ID
         AND Sec.symbol = 'AAA'
       JOIN Hss
         ON Fddd.date = Hss.Hdate
         AND Hss.Code = 1
         AND Hss.Holiday = 1
       ORDER BY Fddd.Date DESC) AS tmp)
       AS TwoHundredAverge;

【讨论】:

  • 这个查询假设Dual 是一个记录的数据库中保存的表,我是否正确?
  • 实际上 dual 是一个虚拟表关键字。实际的查询是子查询
  • 其实不需要双表引用,引用:stackoverflow.com/a/28371433/1688441
猜你喜欢
  • 2021-10-25
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多