【问题标题】:MS Access : Average and Total Calculation in Single QueryMS Access:单个查询中的平均和总计算
【发布时间】:2012-10-24 12:13:39
【问题描述】:

正在使用的数据库表简介 -

我正在研究基于“股票市场价格”的数据库表。我的表已获得以下字段的数据 -

身份证
符号
打开


关闭
音量
音量变化
成交量变化%
OPEN_INT
部门
时间戳

根据当天的股市价格变化,“周一至周五”每天都会将新数据添加到表格中。当前要求基于VOLUME 字段,该字段显示特定股票每天的交易量。

要求—— 分别获取过去 10、15 和 30 天的平均交易量和总交易量。

当前使用的方法 - 我创建了这 9 个单独的查询来获得我想要的结果—— 首先,我创建了这 3 个查询以从当前表中取出最近的 10,15 和 30 个日期:

qryLast10DaysStored
qryLast15DaysStored
qryLast30DaysStored

然后我创建了这 3 个查询来获取各自的平均值:

qrySymbolAvgVolume10Days
qrySymbolAvgVolume15Days
qrySymbolAvgVolume30Days

然后我创建了这 3 个查询来获取各自的 TOTALS:

qrySymbolTotalVolume10Days
qrySymbolTotalVolume15Days
qrySymbolTotalVolume30Days

当前方法面临的问题 - 现在,我的问题是我最终得到了这么多不同的查询,而我想将输出放到一个单一的查询中,如 Excel 工作表的快照所示:

http://i49.tinypic.com/256tgcp.png

需要解决方案 - 有什么方法可以将这些必填字段放入一个查询中,这样我就不必在多个地方查找必填字段?谁能告诉我如何将所有这些单独的查询合二为一 -
A) 将结果从这些单独的单个查询中取出或移动到一个。
B) 或者通过创建一个新的查询来计算所有这些字段,这样就不再需要这些单独的单独查询。我认为这将是一个更好的解决方案。

关于日期的澄清 - 有朋友可能会想,为什么我使用 Top 10,15 和 30 的方法来获取最后的 10,15 和 30 日期值。为什么我不直接使用 PC 日期来获取这些值?或使用类似 -

("VOLUME","tbl-B", "TimeStamp BETWEEN Date() - 10 AND Date()")

答案是我要求我的查询从“TIMESTAMP”字段中“读取”日期,然后针对 LAST / MOST RECENT“10 天、15 天、30 天”执行相应的计算数据在表格中可用,无需担心当前日期是什么。它不应以任何方式取决于当前日期。

如果有更好的方法或者更高效的方式来创建这些查询,请指教。

【问题讨论】:

  • 我不明白日期部分。如果您执行 Top(10) 并按日期字段进行排序。它会起作用吗?你会得到最近 10 个日期
  • 您必须根据列表中的最后 10、15、30 天进行计算吗?所以 datediff 可能超过 10、15 和 30?每个符号的最后几天?

标签: database ms-access


【解决方案1】:

您有单独的查询来计算 10DayTotalVolume10DayAvgVolume。我怀疑你可以在一个查询中计算两者,qry10DayVolumes

SELECT
    b.SYMBOL,
    Sum(b.VOLUME) AS 10DayTotalVolume,
    Avg(b.VOLUME) AS 10DayAvgVolume
FROM
    [tbl-B] AS b INNER JOIN
    qryLast10DaysStored AS q
    ON b.TIMESTAMP = q.TIMESTAMP
GROUP BY b.SYMBOL;

但是,这让我想知道 10DayAvgVolume 是否可以是 10DayTotalVolume / 10 以外的任何东西

类似的考虑适用于 15 天和 30 天的值。

最终,我认为你想要一些基于这样的起点的东西:

SELECT
    q10.SYMBOL,
    q10.[10DayTotalVolume],
    q10.[10DayAvgVolume],
    q15.[15DayTotalVolume],
    q15.[15DayAvgVolume],
    q30.[30DayTotalVolume],
    q30.[30DayAvgVolume]
FROM
    (qry10DayVolumes AS q10
    INNER JOIN qry15DayVolumes AS q15
    ON q10.SYMBOL = q15.SYMBOL)
    INNER JOIN qry30DayVolumes AS q30
    ON q10.SYMBOL = q30.SYMBOL;

假设您按照我为qry10DayVolumes 建议的方法创建了qry15DayVolumesqry30DayVolumes

如果你想减少查询的数量,你可以为每个qry??DayVolumes保存的查询使用子查询,但首先尝试这种方式以确保逻辑正确。

在上面的第二个查询中,由于字段名称以数字开头,可能会出现问题。将这些名称括在方括号中,或使用以字母而不是数字开头的别名将它们重新命名为 qry10DayVolumesqry15DayVolumesqry30DayVolumes

我使用您上传的“2nd Upload.mdb”测试了上面编写的查询,它在 Access 2007 中运行时没有出现错误。以下是该查询结果集的第一行:

SYMBOL 10DayTotalVolume 10DayAvgVolume 15DayTotalVolume 15DayAvgVolume   30DayTotalVolume 30DayAvgVolume
ACC-1             42909         4290.9            54892 3659.46666666667            89669 2988.96666666667

【讨论】:

  • 我也尝试了其他解决方案,但我认为你不能做得比这更好...我想让所有内容都适合单个查询,并且使用 DSUM 是可能的,但它远非作为 SQL 标准,它看起来很糟糕,而且速度很慢!
  • @HansUp 非常感谢你的好主意。现在我觉得很有趣,为什么我自己之前没有想到在同一个查询中计算平均值和总数,而不是分开计算!
  • 是的,你是对的。上面的代码现在工作正常。它正确显示了必填字段。非常感谢您的帮助。
【解决方案2】:

Access 不支持最高级的 SQL 语法和子句,因此这有点小技巧,但它可以工作,并且在您的小样本上运行速度很快。您基本上是在运行 3 个查询,但 Union 子句允许您合并为一个:

select
   Symbol,
   sum([10DayTotalVol]) as 10DayTotalV,
   sum([10DayAvgVol]) as 10DayAvgV,
   sum([15DayTotalVol]) as 15DayTotalV,
   sum([15DayAvgVol]) as 15DayAvgV,
   sum([30DayTotalVol]) as 30DayTotalV,
   sum([30DayAvgVol]) as 30DayAvgV

from (

      select
        Symbol, 
        sum(volume) as 10DayTotalVol, avg(volume) as 10DayAvgVol,
        0 as 15DayTotalVol, 0 as 15DayAvgVol,
        0 as 30DayTotalVol, 0 as 30DayAvgVol
      from
         [tbl-b]
      where
         timestamp >= (select min(ts) from (select distinct top 10 timestamp as ts from [tbl-b] order by timestamp desc ))
      group by
         Symbol   

      UNION

      select
        Symbol, 
        0, 0,
        sum(volume), avg(volume),
        0, 0
      from
         [tbl-b]
      where
         timestamp >= (select min(ts) from (select distinct top 15 timestamp as ts from [tbl-b] order by timestamp desc ))
      group by
         Symbol    

      UNION

      select
        Symbol, 
        0, 0,
        0, 0,
        sum(volume), avg(volume)
      from
         [tbl-b]
      where
         timestamp >= (select min(ts) from (select distinct top 30 timestamp as ts from [tbl-b] order by timestamp desc ))
      group by
         Symbol 
      ) s

group by 
   Symbol

【讨论】:

  • 这个代码太棒了!只需一个查询即可获取所有必填字段,不再需要处理多个查询。优秀的东西 ExactBox。你的方法很棒。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
  • 2023-03-07
  • 2010-12-07
相关资源
最近更新 更多