【问题标题】:Calculation within the subquery, substract an amount from a different table子查询中的计算,从不同的表中减去一个金额
【发布时间】:2014-11-19 16:13:45
【问题描述】:

我已经处理这个查询超过一天了。

从下面第一个查询 (Calls) 中的 Total 列中,我只需将第二个表 (CallsIncrease) 中的 Amount 数字添加或减去日期范围内的月份(从 StartDate 到 EndDate,其中技能等于查询技巧)。

我尝试先创建一个字段,其中包含每个月要减去的金额,然后使用它从总数中减去。

我尝试了以下子查询的不同版本:

Expr1: (
  select amount 
  from (
    SELECT CallsIncrease.Skill, Sum(CallsIncrease.Amount) AS Amount
    FROM CallsIncrease
    GROUP BY CallsIncrease.Skill
  )
  where [skill]=(select [skill] from CallsIncrease)
    And [callmonth] Between (select [startdate] from CallsIncrease)
      And (select [enddate] from CallsIncrease)
)


Expr1: (
  SELECT Sum([%$##@_Alias].amount) AS SumOfamount
  FROM (
    SELECT CallsIncrease.Skill, Sum(CallsIncrease.Amount) AS Amount
    FROM CallsIncrease
    GROUP BY CallsIncrease.Skill)  AS [%$##@_Alias]
    GROUP BY [%$##@_Alias].skill
    HAVING ((([%$##@_Alias].skill)=forecast.skill))
)

调用查询的 SQL:

SELECT
  CDate(DateSerial(Year([ForecastDate]),Month([ForecastDate]),1)) AS ForecastMonth,
  Forecast.Skill,
  Sum(Forecast.NormalizedData) AS Total
FROM Forecast
GROUP BY CDate(DateSerial(Year([ForecastDate]),Month([ForecastDate]),1)),
  Forecast.Skill
HAVING (((Sum(Forecast.NormalizedData)) Is Not Null));

来电查询:

ForecastMonth   Skill               Total
01-Jan-08   Generalist English      56541
01-Jan-08   Generalist Spanish      868
01-Jan-08   Public Safety English   26837
01-Jan-08   Public Safety Spanish   401
01-Jan-08   Total                   34584
01-Jan-08   Utilities English       48332
01-Jan-08   Utilities Spanish       1605
01-Feb-08   Generalist English      52176

来电增加表:

ID  EventID             Skill        StartDate  EndDate     Amount
1   9/5/2008    Generalist English  01-Jan-08   31-Aug-08   1800
3   7/10/2010   Generalist English  01-Jan-08   30-Jun-10   -3000
4   12/1/2011   Generalist English  01-Jan-08   30-Nov-11   2500
5   3/1/2013    Generalist English  01-Jan-08   28-Feb-13   200
6   12/1/2011   Generalist Spanish  01-Jan-08   30-Nov-11   80
7   7/1/2010    Public Safety Eng   01-Jan-08   30-Jun-10   -4700
8   3/10/2009   Utilities English   01-Jan-08   28-Feb-09   7000

我真的希望这一切都有意义,任何帮助将不胜感激。

【问题讨论】:

  • 您使用的是什么关系型数据库?这是 MS Access 吗?
  • 是的,它是 MS Access。

标签: sql ms-access subquery


【解决方案1】:

我想出了以下可怕的混乱。有些希望您的 DBMS 的查询优化器可以用它做一些合理的事情,部分原因是它避免了相关的子查询。事实上,甚至有希望您的 DBMS 或多或少地接受所写的查询。

SELECT
  MonthlyForecast.Month AS ForecastMonth,
  MonthlyForecast.Skill AS Skill,
  (MonthlyForecast.Total + COALESCE(Adjustment.Amount, 0)) AS Total

FROM

  (SELECT
      CDate(DateSerial(Year([ForecastDate]),Month([ForecastDate]),1)) AS Month,
      Forecast.Skill AS Skill,
      SUM(Forecast.NormalizedData) AS Total
    FROM Forecast
    GROUP BY [Month], [Skill]
    HAVING Total IS NOT NULL
  ) MonthlyForecast

  LEFT OUTER JOIN

    (SELECT
        ForecastMonths.Month AS Month,
        CallsIncrease.Skill AS Skill,
        SUM(CallsIncrease.Amount) AS Amount
      FROM
        (SELECT DISTINCT
          CDate(DateSerial(Year([ForecastDate]),Month([ForecastDate]),1)) AS Month
          FROM Forecast
        ) ForecastMonths 
        JOIN CallsIncrease
          ON ForecastMonths.Month
            Between CallsIncrease.StartDate And CallsIncrease.EndDate
      GROUP BY
        [Month], [Skill]
    ) Adjustment

    ON MonthlyForecast.Month = Adjustment.Month
      AND MonthlyForecast.Skill = Adjustment.Skill
;

对于它的价值,将特定日期与日期范围进行比较的需要是一个重要的复杂因素,无论是设计查询还是运行它。除了我上面使用的方法之外,还有其他方法可以处理该问题,但我怀疑它们中的任何一种都会产生更简单的查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多