在同一查询中使用上一年的数据

时间:2017-01-24 17:17:25

标签: sql-server tsql

以下是我当前的查询,我有一个CTE,用于计算按诊所及其各自交易分组的每个会计期间的收入。随后是一个查询,查看每个诊所的工作日,并根据预期的天数查找每日平均值(计算当前天数)和预计收入。

此查询可以正常工作;但是我需要添加更多列。我还想显示去年的收入,所以在这种情况下,我将查询限制为仅显示2016年和第9期,而前一年的收入应该显示2015年的第9期,还需要查看上一年的日期同样(我想这将是一个类似的过程)。

WITH CTE_Revenue AS(
SELECT  c.Clinic,
        c.ClinicID,
        SUM(td.Amount)*-1 AS Revenue,
        p.PeriodID,
        p.FiscalYear
FROM Trans.TransactionHeader th
JOIN Clinic.[Master] c
    ON (th.ClinicID = c.ClinicID)
JOIN Trans.TransactionDetail td
    ON (th.ClinicID = td.ClinicID AND th.TranNum = td.TranNum)
JOIN Clinic.EOD e
    ON (th.ClinicID = e.ClinicID AND th.TranNum BETWEEN e.StartTran AND e.EndTran)
JOIN Clinic.Period p
    ON (CAST(e.TimeRan AS date) BETWEEN p.PeriodStart AND p.PeriodEnd)
AND th.Impacts='C'
GROUP BY c.Clinic, c.ClinicID, p.PeriodID, p.FiscalYear)

SELECT  w.Clinic,
        w.Revenue,
        (w.Revenue / days.CurrentDays) AS DailyAverage,
        (w.Revenue / days.CurrentDays)*d.PeriodDays AS ProjectedRevenue
FROM CTE_Revenue w
JOIN Clinic.Dates d
    ON (w.ClinicID = d.ClinicID AND w.PeriodID = d.PeriodID AND w.FiscalYear = d.FiscalYear)
JOIN (  SELECT DISTINCT
        td.ClinicID,
        COUNT(DISTINCT td.DateEntered) AS CurrentDays,
        p.PeriodID,
        p.FiscalYear
    FROM Trans.TransactionDetail td
    JOIN Clinic.Period p
        ON td.DateEntered BETWEEN p.PeriodStart AND p.PeriodEnd
    GROUP BY td.ClinicID, p.PeriodID, p.FiscalYear) AS days
    ON (w.ClinicID = days.ClinicID AND w.PeriodID=days.PeriodID AND w.FiscalYear = days.FiscalYear)
WHERE w.FiscalYear = 2016
AND w.PeriodID = 9

我想,最终生成的SELECT语句看起来像这样:

SELECT  w.Clinic,
        w.Revenue,
        (w.Revenue / days.CurrentDays) AS DailyAverage,
        (w.Revenue / days.CurrentDays)*d.PeriodDays AS ProjectedRevenue,
        PrevYear.Revenue,
        (PrevYear.Revenue / PrevYear.CurrentDays) AS PYDailyAverage,
        (PrevYear.Revenue / PrevYear.CurrentDays)*d.PeriodDays AS PYCalculated

此查询可能未完全优化,我仍然是SQL的新手。感谢您提前获得任何建议和帮助!

编辑:这是使用SQL Server图表的表结构和关系的图像: Table Diagram

1 个答案:

答案 0 :(得分:1)

您可以使用多个ctes

像这样:

with cte_Revenue as(
  select  
      c.Clinic
    , c.Clinicid
    , Revenue = sum(td.Amount)*-1
    , p.Periodid
    , p.FiscalYear
  from Trans.TransactionHeader th
  inner join Clinic.[Master] c 
     on (th.Clinicid = c.Clinicid)
  inner join Trans.TransactionDetail td 
     on th.Clinicid = td.Clinicid 
    and th.TranNum = td.TranNum
  inner join Clinic.eod e
     on th.Clinicid = e.Clinicid 
    and th.TranNum between e.StartTran and e.EndTran
  inner join Clinic.Period p
      on (cast(e.TimeRan as date) between p.PeriodStart and p.PeriodEnd)
    and th.Impacts='C'
  group by 
      c.Clinic
    , c.Clinicid
    , p.Periodid
    , p.FiscalYear
)
, include_py as (
  select 
        w.Clinic
      , w.Revenue
      , w.Periodid
      , w.FiscalYear
      , DailyAverage = (w.Revenue / days.CurrentDays)
      , ProjectedRevenue = (w.Revenue / days.CurrentDays)*d.PeriodDays 
    from cte_Revenue w
      inner join Clinic.Dates d
         on w.Clinicid = d.Clinicid 
        and w.Periodid = d.Periodid 
        and w.FiscalYear = d.FiscalYear
      inner join (
        select distinct
              td.Clinicid
            , CurrentDays = count(distinct td.DateEntered)
            , p.Periodid
            , p.FiscalYear
          from Trans.TransactionDetail td
            inner join Clinic.Period p
              on td.DateEntered between p.PeriodStart and p.PeriodEnd
          group by 
              td.Clinicid
            , p.Periodid
            , p.FiscalYear
      ) as days
            on w.Clinicid = days.Clinicid 
          and w.Periodid=days.Periodid 
          and w.FiscalYear = days.FiscalYear
    where w.FiscalYear in (2015,2016)
      and w.Periodid = 9
)
select 
    c.Clinic
  , c.FiscalYear
  , c.PeriodId
  , c.Revenue
  , c.DailyAverage
  , c.ProjectedRevenue
  , pyRevenue = p.Revenue
  , pyDailyAverage = p.DailyAverage
  , pyProjectedRevenue = p.ProjectedRevenue
from (select * from include_py where fiscalyear = 2016) c
  left join (select * from include_py where fiscalyear = 2015) p
    on c.Clinic = p.Clinic

Bad Habits to Kick : Using AS instead of = for column aliases - Aaron Bertrand