在子查询中计算,从不同的表中减去一个量

时间:2014-11-19 16:13:46

标签: sql ms-access subquery

我已经在这个查询上工作了一天多了。

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

我尝试先创建一个字段,每个月减去Amount数量,然后用它从总数中减去。

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

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

我真的希望这一切都有意义,任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

我想出了以下可怕的混乱。有一些希望你的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
;

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