SQL Server 2014 Select total for each day - sql

Hello I am working on a dataset for a report in SSRS
and I have a query which gives the total requests in the backlog :
SELECT
COUNT(*) as NB
FROM p_rqt WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p_rqt.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p_rqt.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND p_rqt.OrigCpyInCde LIKE CASE WHEN #Client = 0 THEN '%' ELSE #Client END
AND ((RcvDte < DATEADD(day, 1, #DateDeb) AND RqtEndDte IS NULL) OR
(RcvDte < DATEADD(day, 1, #DateDeb) AND RqtEndDte > DATEADD(day, 1, #DateDeb)))
and I want to retrieve the total amount left per day.
I tried lot of things like this :
SELECT CONVERT(date,rcvdte,103), count(*) as nb
FROM p_rqt p WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND ((RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte IS NULL) OR (RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte > DATEADD(day, 1, '20170901')))
group by CONVERT(date,rcvdte,103)
order by CONVERT(date,rcvdte,103)
I tried inner join subqueries, Sum and other stuff
but all I can manage to do is to have the number of records added per day
and I want something like this :
date: NB:
01/01/2017 1950
02/01/2017 1954 (+4 items)
03/01/2017 1945 (-9 items)
Thank you

Use LAG:
WITH cte AS (
SELECT
CONVERT(date, rcvdte, 103) AS date,
COUNT(*) AS nb
FROM p_rqt p WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK)
ON p_cpy.CpyInCde = p.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31) AND
p.RqtNatInCde IN (74, 75, 76) AND
HeadRqtInCde = 0 AND
((RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte IS NULL) OR (RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte > DATEADD(day, 1, '20170901')))
GROUP BY CONVERT(date, rcvdte, 103)
ORDER BY CONVERT(date, rcvdte, 103)
)
SELECT
t1.date,
(SELECT SUM(t2.nb) FROM cte t2 WHERE t2.date <= t1.date) AS nb,
CASE WHEN t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date) > 0
THEN '(+' + (t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date)) + ' items)'
ELSE '(' + (t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date)) + ' items)'
END AS difference
FROM cte t1
ORDER BY t1.date;

So i found a solution but it is really slow,
i still post the answer anyway
DECLARE #Tb TABLE ( Colonne1 Datetime, Colonne2 INT )
DECLARE #Debut Datetime = '01/09/2017'
WHILE #Debut < '13/09/2017'
BEGIN
DECLARE #Compteur int = (
SELECT
COUNT(1) NB
FROM p_rqt WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p_rqt.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p_rqt.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND p_rqt.OrigCpyInCde LIKE '%'
AND (
(RcvDte < #Debut AND RqtEndDte IS NULL)
OR
(RcvDte < #Debut AND RqtEndDte > #Debut)
)
)
INSERT INTO #Tb (Colonne1, Colonne2) VALUES (#Debut, #Compteur)
SET #Debut = DATEADD(day, 1, #Debut)
IF #Debut > '13/09/2017'
BREAK
ELSE
CONTINUE
END
SELECT * FROM #Tb

Related

SQL Switch/Case in 'where' clause with and

I currently have this query
DECLARE #user uniqueidentifier
, #day_to_find int
, #date DATETIME = getdate()
SELECT
#user = CAST(Value AS uniqueidentifier)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'SuperUser.Id'
SELECT
#day_to_find = CAST(Value AS int)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'Returns.MaxDay'
--INSERT INTO...... //Part not copied for cleaning
SELECT DISTINCT
#user,
#date,
bd.shopping_code,
bd.cod_gender,
bd.book_number,
'03',
'01',
'11',
#user,
#user,
GETDATE(),
GETDATE(),
ean_code,
15,
bd.cod_variation,
FROM bdo.BOOK_DATA bd WITH (NOLOCK)
-- various inner joins...
WHERE
btw.num_catalog IS NOT NULL
AND(
(
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= #day_to_find
OR (cod_catalog = '04'
AND bd.cod_category NOT IN ('children', 'used', 'discounted'))
AND bd.cod_state= '00'
AND bd.cod_variation = '00'
AND NOT EXISTS (SELECT TOP 1
*
FROM BOOK_RETURNS br (NOLOCK)
WHERE br.code = bd.shopping_code
AND br.cod_category = bd.cod_category
AND br.book_number = bd.book_number
AND br.cod_request_returns = 1
AND br.num_progr_bd = bd.prog
AND br.cod_elaboration = '103')
GO
I need to modify this part:
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= #day_to_find
If bd.shopping_code is "B41", "B74", "BT34" the and must become
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 30
In all other cases the and will remain
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= #day_to_find
Is it possible to manage the two cases through the switch case or are there other possible ways?
EDIT 2022/05/13
What if I used a UNION?
DECLARE #user uniqueidentifier
, #day_to_find int
, #date DATETIME = getdate()
SELECT
#user = CAST(Value AS uniqueidentifier)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'SuperUser.Id'
SELECT
#day_to_find = CAST(Value AS int)
FROM BookSoreConfiguration.dbo.Config(NOLOCK)
WHERE Key = 'Returns.MaxDay'
--INSERT INTO...... //Part not copied for cleaning
SELECT DISTINCT
#user,
#date,
bd.shopping_code,
bd.cod_gender,
bd.book_number,
'03',
'01',
'11',
#user,
#user,
GETDATE(),
GETDATE(),
ean_code,
15,
bd.cod_variation,
FROM bdo.BOOK_DATA bd WITH (NOLOCK)
-- various inner joins...
WHERE
bd.shopping_code NOT IN ('B41', 'B74', 'BT34')
AND btw.num_catalog IS NOT NULL
AND(
(
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= #day_to_find
OR (cod_catalog = '04'
AND bd.cod_category NOT IN ('children', 'used', 'discounted'))
AND bd.cod_state= '00'
AND bd.cod_variation = '00'
AND NOT EXISTS (SELECT TOP 1
*
FROM BOOK_RETURNS br (NOLOCK)
WHERE br.code = bd.shopping_code
AND br.cod_category = bd.cod_category
AND br.book_number = bd.book_number
AND br.cod_request_returns = 1
AND br.num_progr_bd = bd.prog
AND br.cod_elaboration = '103')
UNION
SELECT DISTINCT
#user,
#date,
bd.shopping_code,
bd.cod_gender,
bd.book_number,
'03',
'01',
'11',
#user,
#user,
GETDATE(),
GETDATE(),
ean_code,
15,
bd.cod_variation,
FROM bdo.BOOK_DATA bd WITH (NOLOCK)
-- various inner joins...
WHERE
bd.shopping_code IN ('B41', 'B74', 'BT34')
AND btw.num_catalog IS NOT NULL
AND(
(
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 30
OR (cod_catalog = '04'
AND bd.cod_category NOT IN ('children', 'used', 'discounted'))
AND bd.cod_state= '00'
AND bd.cod_variation = '00'
AND NOT EXISTS (SELECT TOP 1
*
FROM BOOK_RETURNS br (NOLOCK)
WHERE br.code = bd.shopping_code
AND br.cod_category = bd.cod_category
AND br.book_number = bd.book_number
AND br.cod_request_returns = 1
AND br.num_progr_bd = bd.prog
AND br.cod_elaboration = '103')
GO
Since the left part remains the same and only the value can be different, you could try the following approach (CASE 'returns' the value of the right part):
AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >=
CASE
WHEN bd.shopping_code IN ('B41', 'B74', 'BT34') THEN 30
ELSE #day_to_find
END
WHERE
(
bd.shopping_code IN ('B41', 'B74', 'BT34') AND DATEDIFF(DAY, btw.sell_date, GETDATE()) >= 30
OR
DATEDIFF(DAY, btw.sell_date, GETDATE()) >= #day_to_find
)
AND ...

How to make a CASE in the where clause

I have this stored procedure
ALTER PROC rpt_ItemsSales_DayMonthYear_Week --'2022-01-01','2022-02-1',0
#from datetime,
#to datetime,
#ByOpenShift bit
AS
SET DATEFIRST 7
;WITH Weeks (WeeksNumber) AS
(SELECT 1
UNION ALL
SELECT WeeksNumber + 1
FROM Weeks
WHERE WeeksNumber < 4)
SELECT SalesPos_Dtls.ItemName,
SUM(SalesPos_Dtls.Qty) AS SumQty,
SUM(SalesPos_Dtls.TotalPrice) AS SumTotal,
CAST(SalesPos.StartDate AS date) AS StartDate,
N'الاسبوع ' + CAST(FLOOR((DATEPART(DAY, SalesPos.StartDate) - 2) / 7) + 1 AS varchar(10)) AS Week,
[dbo].[StartOfWeek](SalesPos.StartDate) AS FirstDay,
SalesPos_Dtls.ItemId
FROM Weeks
LEFT JOIN SalesPos ON CAST(FLOOR((DATEPART(DAY, SalesPos.StartDate) - 2) / 7) + 2 AS varchar(10)) = Weeks.WeeksNumber
AND (status = 'IsPosted')
LEFT JOIN SalesPos_Dtls ON SalesPos.ID = SalesPos_Dtls.OrderId
LEFT JOIN Shift_Open ON Shift_Open.Shift_Id = SalesPos.Shift_Id
WHERE (#from <= SalesPos.StartDate
OR #from IS NULL)
AND (#to >= SalesPos.StartDate
OR #to IS NULL)
GROUP BY SalesPos_Dtls.ItemName,
SalesPos_Dtls.ItemCode,
Weeks.WeeksNumber,
CAST(SalesPos.StartDate AS date),
SalesPos.StartDate,
SalesPos_Dtls.ItemId;
That I want it to if the #ByOpenShift is 0 then the #from and #to will be selected from SalesPos.StartDate else it wil be selected from Shift_Open.OpenDate
edit:
after using ADN/OR logic it worked fine.
((((CAST(SalesPos.StartDate AS date)>= CAST(#from AS date)and CAST(SalesPos.StartDate AS date) <=CAST(#to AS date)) or(#from is null) and (#to is null) )
and (#ByOpenShift = 0 or #ByOpenShift is null))
or ((CAST(Shift_Open.OpenDate AS date)>= CAST(#from AS date)and CAST(SalesPos.StartDate AS date) <=CAST(#to AS date))
or(#from is null) and (#to is null)))

Conversion of string to DateTime & using conversion in Where Clause - DateDiff

I have a string column that contains dates. I want to convert string to date so that i can use the Date Logic ahead.
I have converted the string to DateTime but while applying the logic in the Where clause it doesn't allow me to use the Column.
SELECT a.code,
CONVERT(DATETIME,b.[FieldValue],103) as [Date1]
FROM [dbo].employeedetail as A join [dbo].CustomeFieldDetail as B
on A.Id = B.EMployeeid
WHERE a.empstatus = 1
AND B.CustomeFieldName = 'PASSPORT' AND
( Datediff(dd, Getdate(), Dateadd(yyyy, Datediff(yyyy, b.[Date1],
Getdate())
+
1, b.[Date1]))
+ 1 ) % 366 = 50
Can anyone help me?
Use APPLY to introduce a reusable expression.
SELECT a.code,
c.[Date1]
FROM [dbo].employeedetail as A
JOIN [dbo].CustomeFieldDetail as B ON A.Id = B.EMployeeid
CROSS APPLY (
SELECT CONVERT(DATETIME,b.[FieldValue],103) as [Date1]
) c
WHERE a.empstatus = 1
AND B.CustomeFieldName = 'PASSPORT' AND
( Datediff(dd, Getdate(), Dateadd(yyyy, Datediff(yyyy, c.[Date1],
Getdate())
+
1, c.[Date1]))
+ 1 ) % 366 = 50
A better solution is store dates as DATE, DATETIME, not strings.
Using CTE results in an even more compact query:
WITH B AS (
SELECT *, CONVERT(DATETIME, [FieldValue], 103) AS [Date1]
FROM [dbo].CustomeFieldDetail
WHERE (CustomeFieldName = 'PASSPORT')
)
SELECT A.code, B.[Date1]
FROM [dbo].EmployeeDetail AS A JOIN B ON A.Id = B.EMployeeid
WHERE (A.empstatus = 1)
AND (((DATEDIFF(dd, GETDATE(),
DATEADD(yyyy, DATEDIFF(yyyy, B.[Date1], GETDATE()) + 1, B.[Date1])) + 1)
% 366) = 50)

Data are always showing of one furnace in sql server

I am working on an sql query where i will give a date from which Month and year will be determined. Then the record will be selected from Lab_Analysis and Lab_CSAnalysis table of any Furnace and Product ID. For this i Did following
Declare #Furnace varchar(50)='FUR-A'
Declare #Product bigint=1
Declare #sd date
Declare #ed date
Declare #Date date='02-02-2019'
SET #sd=(SELECT DATEADD(s,1,DATEADD(mm, DATEDIFF(m,0,#Date),0)))
SET #ed=(SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#Date)+1,0)))
;WITH dates AS (
SELECT #sd as theDate
UNION ALL
SELECT DATEADD(day, 1, theDate)
FROM dates
WHERE DATEADD(day, 1, theDate) <= #ed
)
SELECT DATEPART(dd, D.theDate) AS 'Day', ISNULL(LS.QtyMT, 0) AS QtyMt, ISNULL(SUM(L.Mn), 0) AS Mn, ISNULL(SUM(L.Si), 0) AS Si, ISNULL(SUM(L.P), 0) AS P,
ISNULL(LS.Carbon, 0) AS C, ISNULL(LS.Sulphur, 0) AS S, ISNULL(SUM(L.MnO), 0) AS MnO, ISNULL(SUM(L.CaO), 0) AS CaO, ISNULL(SUM(L.AI2O3), 0)
AS AI2O3, ISNULL(SUM(L.MgO), 0) AS MgO, ISNULL(SUM(L.Fe2O3), 0) AS Fe2O3, ISNULL(SUM(L.SiO2), 0) AS SiO2, ISNULL(SUM(L.Basicity), 0) AS Basicity
FROM Lab_Product AS LP INNER JOIN
Lab_Analysis AS L ON LP.ID = L.Product RIGHT OUTER JOIN
dates AS D ON L.Date = theDate LEFT OUTER JOIN
Lab_CSAnalysis AS LS ON LS.Date = L.Date AND (LP.ID = 1 AND L.Furnace = #Furnace AND LS.Furnace=#Furnace)
GROUP BY D.theDate, LS.QtyMT, LS.Carbon, LS.Sulphur
Here i want to view Record of Furnace='A' and ProductID=1. Then the above query is correct Output. There is no Record in Other than Furnace 'A' and Product ID=1. But when i want to View records of Furnace 'B' then it is still showing records of Furnace 'A'. How to solve this?
because of your filter on the left join. I made some changing over your query
Declare #Furnace varchar(50)='FUR-A'
Declare #Product bigint=1
Declare #sd date
Declare #ed date
Declare #Date date='02-02-2019'
SET #sd=(SELECT DATEADD(s,1,DATEADD(mm, DATEDIFF(m,0,#Date),0)))
SET #ed=(SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#Date)+1,0)))
;WITH dates AS (
SELECT #sd as theDate
UNION ALL
SELECT DATEADD(day, 1, theDate)
FROM dates
WHERE DATEADD(day, 1, theDate) <= #ed
)
SELECT DATEPART(dd, D.theDate) AS 'Day',
ISNULL(LS.QtyMT, 0) AS QtyMt,
ISNULL(SUM(L.Mn), 0) AS Mn,
ISNULL(SUM(L.Si), 0) AS Si,
ISNULL(SUM(L.P), 0) AS P,
ISNULL(LS.Carbon, 0) AS C,
ISNULL(LS.Sulphur, 0) AS S,
ISNULL(SUM(L.MnO), 0) AS MnO,
ISNULL(SUM(L.CaO), 0) AS CaO,
ISNULL(SUM(L.AI2O3), 0) AS AI2O3,
ISNULL(SUM(L.MgO), 0) AS MgO,
ISNULL(SUM(L.Fe2O3), 0) AS Fe2O3,
ISNULL(SUM(L.SiO2), 0) AS SiO2,
ISNULL(SUM(L.Basicity), 0) AS Basicity
FROM
dates
INNER JOIN Lab_Analysis AS L ON L.Date = dates.theDate AND L.Furnace = #Furnace
LEFT JOIN Lab_Product AS LP ON LP.ID = L.Product AND LP.ID = 1
LEFT JOIN Lab_CSAnalysis AS LS ON LS.Date = L.Date AND (L.Furnace = LS.Furnace)
GROUP BY
D.theDate, LS.QtyMT, LS.Carbon, LS.Sulphur

TSQL calculating from combined queries

I currently have six queries in which I take the results and use a spreadsheet to calculate two different final percentages. I believe that it can be done in a single query, and without a spreadsheet, but I am not knowledgeable enough in SQL to figure it out. I am hoping for some direction from the amazing SQL Gods here on SO.
We have several locations, and calculate a Past Due % and a Past Due Fallout %, per location, based on the average of two other percentages:
Past Due Dollars ÷ Projected Dollars = Past Due Float %
Past Due Units ÷ Total Active Units = Past Due Unit %
( Past Due Unit % + Past Due Dollar % ) / 2 = Past Due %
Fallout uses the same calculations, but looks at what the amounts will be tomorrow.
SOLVED: I spent time learning about sub-queries, and joined them by the STID. Thanks for all who assisted and helped guide me in the
correct direction.
Here is my final code:
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
You can't use variables like that and you can't do this in one aggregate query because it's going to create a massive Cartesian product and give you incorrect results.
You could use CTE's or subqueries for each query you have listed and then join them together on the STID and apply your formulas.
example...
/* 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
You never set the variables to any real value, the you proceed to select the useless variable in a irrelevant SELECT statement.
in the following line
Set #pdD = Sum( Case When a.DueDate < GetDate() Then DateDiff(d,a.DueDate,#runDate) * (a.WeeklyRate/7) )
You are not stating where s.DueDate comes from. It wont even compile.
In this SELECT the table is completely irrelevant
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
This is an example to how you should set the values before you try to do calculations with the variables.
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
My problem was a lack of knowledge and understanding of SQL, which I'm improving on. Here is what I ended up with that gave me the result I desired, whether the most efficient or not.
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