2016-04-14 146 views
0

我目前有六個查詢,其中我拿出結果並使用電子表格來計算兩個不同的最終百分比。我相信它可以在單個查詢中完成,並且不需要電子表格,但是我在SQL方面的知識還不夠豐富。我希望從這裏的神奇SQL神們獲得一些指導。通過組合查詢計算TSQL

我們有幾個位置,並計算逾期%和過期輻射%,每個位置的基礎上,平均另外兩個百分比:

  • 過期元÷預計美元= 過期浮法%
  • 逾期單位數÷總活性單位= 逾期單位%
  • 逾期單元% + 過去由於美元%)/ 2 = 逾期%

輻射使用相同的計算,但看什麼的金額將是明天。

已解決:我花時間學習了子查詢,並加入了STID。感謝所有幫助和指導我正確指導 的人。

這是我的最終代碼:

SET DATEFIRST 1; 
DECLARE @Today date = dbo.getdateparam(92,999); 
DECLARE @TodayNum int = DATEPART(dw, @Today); 
DECLARE @Saturday date = DATEADD(DAY, ([email protected])%7, @Today); 
DECLARE @PrevSat date = DATEADD(DAY, -7, @Saturday); 

Select store.STID As Store, 
    Proj.ProjRent As Projected, 
    PDRent.PastDueDollars As PDRent, 
    UOR.Units As UOR, 
    PDUnits.UnitsPD As PDUnits, 
    (PDRent.PastDueDollars/Proj.ProjRent) * 100 As FloatPerc, 
    (Cast(PDUnits.UnitsPD As Decimal)/Cast(UOR.Units As Decimal)) * 
    100 As UnitPerc, 
    Cast(Round((((PDRent.PastDueDollars/Proj.ProjRent) * 100) + 
    ((Cast(PDUnits.UnitsPD As Decimal(18,4))/Cast(UOR.Units As Decimal(18,4))) * 
    100))/2, 2) As Decimal(18,2)) As PDPerc, 
    Reds.RedsPD As PDReds, 
    Round(Cast(Reds.RedsPD As Float)/Cast(UOR.Units As Float) * 100, 
    2) As RedsPerc 
From 
-- Stores 
(Select Distinct Stores.STID, 
    Stores.StoreName, 
    Stores.EMail, 
    Stores.ManagersName 
    From Stores 
    Where Stores.STID Not In (7, 999)) As store 

    -- Projected Rent 
    Left Join (Select CashProj.STID, 
    Sum(CashProj.ProjectedRental) As ProjRent 
    From CashProj 
    Where CashProj.ProjectionDate Between DateAdd(mm, DateDiff(mm, 0, @Today), 
    0) And DateAdd(mm, DateDiff(mm, 0, @Today) + 1, 0) 
    Group By CashProj.STID) As Proj On store.STID = Proj.STID 

    -- Past Due Float 
    Left Join (Select Agreemnt.STID As STID, 
    Sum(DateDiff(d, Agreemnt.DueDate, (Case DatePart(dw, @Today) 
     When '1' Then DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, 
     @Today)) % 7, @Today)) When '6' Then @Today 
     Else DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) 
    End)) * Round(Agreemnt.WeeklyRate/7, 2)) As PastDueDollars, 
    DatePart(dw, @Today) As TodayNum, 
    DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, 
    @Today)) As PrevSat, 
    DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) As Saturday 
    From Agreemnt 
    Where Agreemnt.AStatID = 1 And Agreemnt.DueDate < (Case DatePart(dw, 
     @Today) 
     When '1' Then DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, 
     @Today)) % 7, @Today)) When '6' Then @Today 
     Else DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) 
    End) And Agreemnt.RentToRent = 0 
    Group By Agreemnt.STID) As PDRent On store.STID = PDRent.STID 

    -- Units On Rent 
    Left Join (Select Invntry.STID, 
    Cast(Count(Invntry.StockNumber) As Int) As Units 
    From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And 
     Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And 
     Agreemnt.AgreeID = AgreHist.AgreeID And Agreemnt.AStatID = 
     AgreHist.AStatID 
    Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And 
    Agreemnt.AStatID = 1 
    Group By Invntry.STID) As UOR On store.STID = UOR.STID 

    -- Past Due Units 
    Left Join (Select Invntry.STID, 
    Cast(Count(Invntry.StockNumber) As Int) As UnitsPD 
    From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And 
     Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And 
     Agreemnt.AgreeID = AgreHist.AgreeID And AgreHist.AStatID = 
     Agreemnt.AStatID 
    Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And 
    Agreemnt.AStatID = 1 And Agreemnt.DueDate < (Case @TodayNum When '1' Then @PrevSat When '6' Then @Today Else @Saturday End) And Agreemnt.RentToRent = 0 
    Group By Invntry.STID) As PDUnits On store.STID = PDUnits.STID 

    -- Reds 
    Left Join (Select Invntry.STID, 
    Count(Invntry.StockNumber) As RedsPD 
    From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And 
     Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And 
     Agreemnt.AgreeID = AgreHist.AgreeID And Agreemnt.AStatID = 
     AgreHist.AStatID 
    Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And 
    Agreemnt.AStatID = 1 And Agreemnt.DueDate < DateAdd(day, -15, Case 
     Cast(DatePart(dw, @Today) As Int) 
     When '1' Then Cast(DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, 
     @Today)) % 7, @Today)) As Date) 
     When '6' Then Cast(@Today As Date) 
     Else Cast(DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) As 
     Date) End) And Agreemnt.RentToRent = 0 
    Group By Invntry.STID) As Reds On store.STID = Reds.STID 
Order By Store 
+0

沒有閱讀所有這些細節..我有一個簡單的問題給你。在所有這些查詢中,是否有任何字段(表中的列)將所有這些查詢關聯在一起?如果是這樣,你的答案很簡單,你可以使用派生查詢加入所有這些查詢。它看起來像你的結果集說是的有..所以你會做'SELECT .. FROM FirstQuery t1 JOIN(SELECT .. FROM YourSecondQuery)t2 ON t2.SomeID = t1.SomeID',你從那裏繼續。 – JonH

+0

@JonH所有的共同字段Agreemnt.STID,ProjectedDollars除外,其中查詢單個表。 – thelincster

+0

爲了關聯表需要有一些關係,如果你沒有這種關係,你如何期待sql server給你這個查詢......它不能因爲你不能告訴它你想要什麼。你需要確定這張表如何鏈接到其他表。 – JonH

回答

0

不能使用這樣的變量,因爲它會創建一個巨大的笛卡爾乘積,給你不正確的結果,你不能這樣做在一個聚集查詢。

您可以對列出的每個查詢使用CTE或子查詢,然後將它們連接到STID上並應用您的公式。

例如...

/* declare all variables here */ 
DECLARE @dayNum INT; 
SET @dayNum = datepart(dw, getdate()); 

with PastDueDollars as (
    select ... from ... group by STID 
), ProjectedDollers as (
    select ... from ... group by STID 
), PastDueUnits as (
    select ... from ... group by STID 
), preFinal as (

    select 
     PastDueDollarRatio = pdd.PastDueDollars/pd.ProjRent, 
     PastDueUnitRatio = pdu.UnitsPD/tau.TotalActiveUnits 
     /* add the other calculations */ 
    from 
     PastDueDollars pdd 
     inner join ProjectedDollers pd on pdd.STID = pd.STID 
     inner join PastDueUnits pdu on pdu.STID = pd.STID 
     /* join more CTEs */ 
) 

select 
    f.*, 
    PastDueRatio = (f.PastDueDollarRatio + f.PastDueUnitRatio)/2 
    /* and so on for the other calculations of calculations... */ 
from 
    preFinal f 
+0

這看起來有點像我可能需要的,但那麼我將如何計算最終的百分比? – thelincster

+0

我想我不明白的是,如果我爲每個查詢使用CTE並將它們連接到STID上,我如何從查詢結果創建變量,運行我的計算,然後輸出查詢結果和計算結果全部在一起。我剛剛還沒有那個「啊哈」時刻呢......:/ – thelincster

+0

@thelincster你不需要變量..你可以在最終查詢的select子句中進行計算。 – dotjoe

0

你從來沒有設置的變量對任何真正的價值,你將繼續選擇在無關緊要的SELECT語句中的無用的變量。

以下行

Set @pdD = Sum(Case When a.DueDate < GetDate() Then DateDiff(d,a.DueDate,@runDate) * (a.WeeklyRate/7)) 

你是不是說明這裏s.DueDate從何而來。它甚至不會編譯。

在此選擇表是完全不相干的

Select a.STID as STID, 
@pdU As PastDueUnits, 
@activeU As ActiveUnits, 
@pdD As PastDueDollars, 
@projRent As ProjRent, 
@pdP As PastDuePerc, 
@foU As FalloutUnits, 
@foD As FalloutDollars, 
@foP As FalloutPerc 

FROM Agreemnt a INNER JOIN CashProj on a.STID = CashProj.STID JOIN Invntry i ON a.STID = i.STID JOIN AgreHist h On i.InvID = h.InvID And i.STID = h.STID INNER JOIN Agreemnt a On a.STID = h.STID AND a.AgreeID = h.AgreeID AND a.AStatID = h.AStatID 
WHERE a.RentToRent = 0 AND i.InvStatID = 11 AND i.DisposalDate IS NULL AND a.AStatID = 1 AND a.DueDate < DateAdd(d, @runDate, GetDate()) 
GROUP BY a.STID 
ORDER BY a.STID 

這是一個例子,你試圖做的變量計算之前,你應該如何設置的值。

DECLARE @dayNum INT; 
SET @dayNum = datepart(dw, getdate()); 

Select Invntry.STID, 
    @foU = COUNT(Invntry.StockNumber) 
From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And 
    Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And Agreemnt.AgreeID = 
    AgreHist.AgreeID And Agreemnt.AStatID = AgreHist.AStatID 
Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And 
    Agreemnt.AStatID = 1 And Agreemnt.DueDate < DateAdd(d, Case @dayNum When '1' Then -2 When '2' Then 1 When '3' Then 1 When '4' Then 1 
    When '5' Then 1 When '6' Then 0 When '7' Then -1 End, GetDate()) And Agreemnt.RentToRent = 0 
Group By Invntry.STID 
+0

請原諒我缺乏的知識...如果我這樣做,與選擇語句內的變量,那麼我將不得不運行多個查詢?我將如何堆疊它們? – thelincster

+0

要堆疊它們,請遵循@dotjoe建議的方式。您先選擇然後在他的exmaple的最後一個SELECT中分配。 –

+0

重新閱讀@dotjoe建議後,我想我明白了。我仍然無法想到的是如何從這些計算中計算兩個最終百分比並輸出數據。 – thelincster

0

我的問題是缺乏知識和SQL的理解,這我就提高。這就是我最終得到的結果,它給了我想要的結果,無論是否最有效。

SET DATEFIRST 1; 
DECLARE @Today date = dbo.getdateparam(92,999); 
DECLARE @TodayNum int = DATEPART(dw, @Today); 
DECLARE @Saturday date = DATEADD(DAY, ([email protected])%7, @Today); 
DECLARE @PrevSat date = DATEADD(DAY, -7, @Saturday); 

Select store.STID As Store, 
    Proj.ProjRent As Projected, 
    PDRent.PastDueDollars As PDRent, 
    UOR.Units As UOR, 
    PDUnits.UnitsPD As PDUnits, 
    (PDRent.PastDueDollars/Proj.ProjRent) * 100 As FloatPerc, 
    (Cast(PDUnits.UnitsPD As Decimal)/Cast(UOR.Units As Decimal)) * 100 As UnitPerc, 
    Cast(Round((((PDRent.PastDueDollars/Proj.ProjRent) * 100) + ((Cast(PDUnits.UnitsPD As Decimal(18,4))/Cast(UOR.Units As Decimal(18,4))) * 100))/2, 2) As Decimal(18,2)) As PDPerc, 
    Reds.RedsPD As PDReds, 
    Round(Cast(Reds.RedsPD As Float)/Cast(UOR.Units As Float) * 100,2) As RedsPerc 
From 
    -- Stores 
(Select Distinct Stores.STID, 
    Stores.StoreName, 
    Stores.EMail, 
    Stores.ManagersName 
    From Stores 
    Where Stores.STID Not In (7, 999)) As store 

    -- Projected Rent 
    Left Join (Select CashProj.STID, 
    Sum(CashProj.ProjectedRental) As ProjRent 
    From CashProj 
    Where CashProj.ProjectionDate Between DateAdd(mm, DateDiff(mm, 0, @Today),0) And DateAdd(mm, DateDiff(mm, 0, @Today) + 1, 0) 
    Group By CashProj.STID) As Proj On store.STID = Proj.STID 

    -- Past Due Float 
    Left Join (Select Agreemnt.STID As STID, 
    Sum(DateDiff(d, Agreemnt.DueDate, (Case DatePart(dw, @Today) When '1' Then DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today)) When '6' Then @Today 
     Else DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) End)) * Round(Agreemnt.WeeklyRate/7, 2)) As PastDueDollars, 
    DatePart(dw, @Today) As TodayNum, 
    DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, 
@Today)) As PrevSat, 
    DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) As Saturday 
    From Agreemnt 
    Where Agreemnt.AStatID = 1 And Agreemnt.DueDate < (Case DatePart(dw, @Today) When '1' Then DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today)) When '6' Then @Today Else DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) End) And Agreemnt.RentToRent = 0 
    Group By Agreemnt.STID) As PDRent On store.STID = PDRent.STID 

    -- Units On Rent 
    Left Join (Select Invntry.STID, 
    Cast(Count(Invntry.StockNumber) As Int) As Units 
    From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And 
     Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And 
     Agreemnt.AgreeID = AgreHist.AgreeID And Agreemnt.AStatID = 
     AgreHist.AStatID 
    Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And Agreemnt.AStatID = 1 
    Group By Invntry.STID) As UOR On store.STID = UOR.STID 

    -- Past Due Units 
    Left Join (Select Invntry.STID, 
    Cast(Count(Invntry.StockNumber) As Int) As UnitsPD 
    From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And 
     Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And 
     Agreemnt.AgreeID = AgreHist.AgreeID And AgreHist.AStatID = 
     Agreemnt.AStatID 
    Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And 
    Agreemnt.AStatID = 1 And Agreemnt.DueDate < (Case @TodayNum When '1' Then @PrevSat When '6' Then @Today Else @Saturday End) And Agreemnt.RentToRent = 0 
    Group By Invntry.STID) As PDUnits On store.STID = PDUnits.STID 

    -- Reds 
    Left Join (Select Invntry.STID, 
    Count(Invntry.StockNumber) As RedsPD 
    From Invntry 
    Inner Join AgreHist On Invntry.InvID = AgreHist.InvID And Invntry.STID = AgreHist.STID 
    Inner Join Agreemnt On Agreemnt.STID = AgreHist.STID And Agreemnt.AgreeID = AgreHist.AgreeID And Agreemnt.AStatID = AgreHist.AStatID 
    Where Invntry.InvStatID = 11 And Invntry.DisposalDate Is Null And Agreemnt.AStatID = 1 And Agreemnt.DueDate < DateAdd(day, -15, Case Cast(DatePart(dw, @Today) As Int) When '1' Then Cast(DateAdd(DAY, -7, DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today)) As Date) When '6' Then Cast(@Today As Date) Else Cast(DateAdd(DAY, (6 - DatePart(dw, @Today)) % 7, @Today) As Date) End) And Agreemnt.RentToRent = 0 
    Group By Invntry.STID) As Reds On store.STID = Reds.STID 
Order By Store