2017-01-24 4 views
1

以下は私の現在のクエリです。クリニックとそのそれぞれのトランザクションによってグループ化された各会計期間の収益を計算する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

あなたはこのように複数の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

+0

これは素晴らしい、洞察に感謝します –

+0

ハッピー助けて! @OMAsphyxiate – SqlZim

+0

これを2016/2015だけに限定されない場所に調整する最良の方法は、最終SELECTステートメントから見ている前年のデータをw/e年に適用することです –

関連する問題