以下是我当前的查询,我有一个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的新手。感谢您提前获得任何建议和帮助!
答案 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