我目前有六个查询,我在其中查看结果并使用电子表格计算两个不同的最终百分比。我相信它可以在一个查询中完成,并且没有电子表格,但我在SQL中不够了解它。我希望在这里有来自神奇的SQL神的方向。
我们有多个地点,并根据其他两个百分比的平均值计算每个地点的过期时间百分比和过期时间辐射百分比:
Fallout使用相同的计算,但会查看明天的金额。
已解决:我花时间了解子查询,并由STID加入。感谢所有协助并帮助指导我的人 正确的方向。
这是我的最终代码:
SET DATEFIRST 1;
DECLARE @Today date = dbo.getdateparam(92,999);
DECLARE @TodayNum int = DATEPART(dw, @Today);
DECLARE @Saturday date = DATEADD(DAY, (6-@TodayNum)%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 :(得分:0)
您永远不会将变量设置为任何实际值,您将继续在无关的SELECT语句中选择无用变量。
在以下一行
Set @pdD = Sum( Case When a.DueDate < GetDate() Then DateDiff(d,a.DueDate,@runDate) * (a.WeeklyRate/7) )
您没有说明s.DueDate的来源。它甚至不会编译。
在此SELECT中,该表完全不相关
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
答案 1 :(得分: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
答案 2 :(得分:0)
我的问题是缺乏对SQL的了解和理解,我正在改进。这就是我最终得到的结果,它给了我想要的结果,无论效率是否最高。
SET DATEFIRST 1;
DECLARE @Today date = dbo.getdateparam(92,999);
DECLARE @TodayNum int = DATEPART(dw, @Today);
DECLARE @Saturday date = DATEADD(DAY, (6-@TodayNum)%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