SQL Switch/Case in 'where' clause with and - sql

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 ...

Related

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)))

SQL Server 2014 Select total for each day

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

How to show monthly data even if there are no results yet SQL Server 2008

So I wrote a script that would show monthly premium. Say if you want to view the total premium up to November, you can pass through a parameter in in SSRS to pick 1/1/2016 - 11/30/2016. This would only show the data up until november, hoever, I would like to show it up until december even if there are no records there. How do I go about doing this in SQL? Here is my script so far:
SELECT lc.[Date]
,lc.Carrier
,lc.[Direct Ceded Written Premium]
,cast(cast(year(lc.[date]) as varchar(4)) + '-' + cast(month(lc.[date]) as varchar(2)) + '-01' as date) as [begofmonth]
from
(
SELECT
CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN cast(pd.TransactionDate as DATE)
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN cast(pd.EffectiveDate as DATE)
ELSE cast(pd.TransactionEffDate as date)
END AS [Date]
,CASE WHEN LEFT(PD.POLICYNUM, 3) = 'ORV'
THEN 'Palomar Value Select OR'
WHEN LEFT(PD.POLICYNUM, 3) = 'VSE'
THEN 'Palomar Value Select CA'
WHEN LEFT(PD.POLICYNUM, 3) = 'WAV'
THEN 'Palomar Value Select WA'
ELSE 'Palomar' END AS [Carrier]
,ISNULL(SUM(pd.WrittenPremium), 0) AS [Direct Ceded Written Premium]
FROM premdetail pd
JOIN transactionpremium tp ON pd.systemid = tp.systemid
AND pd.transactionpremiumid = tp.id
JOIN transactionhistory th ON tp.systemid = th.systemid
AND tp.cmmcontainer = th.cmmcontainer
AND tp.parentid = th.id
JOIN basicpolicy bp ON th.systemid = bp.systemid
AND th.cmmcontainer = bp.cmmcontainer
AND th.parentid = bp.id
WHERE
(CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN pd.TransactionDate
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN pd.EffectiveDate
ELSE pd.TransactionEffDate
END) > = CAST(#StartDate AS DATE)
AND (CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN pd.TransactionDate
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN pd.EffectiveDate
ELSE pd.TransactionEffDate
END) < CAST(#EndDate + 1 AS DATE)
AND (bp.carriercd = #ResEQCarrierCd
OR #ResEQCarrierCd = 'All')
GROUP BY
CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN cast(pd.TransactionDate as DATE)
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN cast(pd.EffectiveDate as DATE)
ELSE cast(pd.TransactionEffDate as date)
END
,CONVERT(VARCHAR, pd.EffectiveDate, 101)
,CONVERT(VARCHAR, pd.ExpirationDate, 101)
,CASE
WHEN LEFT(PD.POLICYNUM, 3) = 'ORV'
THEN 'Palomar Value Select OR'
WHEN LEFT(PD.POLICYNUM, 3) = 'VSE'
THEN 'Palomar Value Select CA'
WHEN LEFT(PD.POLICYNUM, 3) = 'WAV'
THEN 'Palomar Value Select WA'
ELSE 'Palomar'
END
,CASE
WHEN pd.TransactionCode = 'EN' THEN CONVERT(VARCHAR, th.TransactionEffectiveDt, 101)
ELSE ''
END
,CONVERT(VARCHAR, DATEADD(ms, -3, DATEADD(mm, DATEDIFF(m, 0, th.transactiondt) + 1, 0)), 101)
,CASE
WHEN pd.TransactionEffDate < CAST(CONVERT(VARCHAR, pd.TransactionDate, 101) AS SMALLDATETIME) THEN CONVERT(VARCHAR, pd.TransactionDate, 101)
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN CONVERT(VARCHAR, pd.EffectiveDate, 101)
ELSE CONVERT(VARCHAR, pd.TransactionEffDate, 101)
END
) lc
ORDER BY lc.[Date], lc.[Carrier], lc.[Direct Ceded Written Premium]
With the parameter that I have, it would only show up until November. However, I would like it to show the whole year, up to December at in this case, even if there are no data there since I didn't pick the enddate variable to be december. I attached an example screenshot of what it should look like when exported to excel.
Just to give you an idea:
declare #tbl TABLE(ID INT IDENTITY,SomeValue VARCHAR(100),SomeDate DATE);
INSERT INTO #tbl VALUES('Some date in March',{d'2016-03-05'}),('Some date in June',{d'2016-06-30'});
WITH AllMonths AS
(
SELECT 1 AS MonthIndex
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
UNION ALL SELECT 11
UNION ALL SELECT 12
)
SELECT MonthIndex
,t.*
FROM AllMonths
LEFT JOIN #tbl AS t ON MONTH(t.SomeDate)=MonthIndex
The result
1 NULL NULL NULL
2 NULL NULL NULL
3 1 Some date in March 2016-03-05
4 NULL NULL NULL
5 NULL NULL NULL
6 2 Some date in June 2016-06-30
7 NULL NULL NULL
8 NULL NULL NULL
9 NULL NULL NULL
10 NULL NULL NULL
11 NULL NULL NULL
12 NULL NULL NULL
There are many ways to create a tally table
CTE with ROW_NUMBER()
A list like in my example
A physical table
It is a good idea to maintain a numbers/DATE table!
In a previous answer I showed one way to create such a table.

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

Error message running query - Column name or number of supplied values does not match table definition

I am attempting to update a stored procedure and have added u.DIVISION in the code however I am not getting the error message
Column name or number of supplied values does not match table definition.
Any suggestions on what I might be missing?
SET ansi_nulls ON
go
SET quoted_identifier ON
go
ALTER PROCEDURE [dbo].[Slx_activity]
AS
DECLARE #ReportStartDate DATETIME,
#ReportEndDate DATETIME
DECLARE #Today DATETIME
SET #Today = Getdate()
DECLARE #Diff INT
SET #Diff = Datediff(day, Dateadd(day, 5, 0), #Today)
SET #ReportEndDate = Dateadd(day, #Diff - #Diff % 7, Dateadd(day, 5, 0))
SET #ReportStartDate = Datediff(day, 6, #ReportEndDate)
IF Object_id('SLXActivity', 'U') IS NOT NULL
DROP TABLE slxactivity;
SELECT ' Current Activity:' + ' ' + p.[text] AS [TYPE],
h.createdate,
p.[text],
h.[description],
h.startdate,
Cast (NULL AS DATETIME) AS COMPLETEDDATE,
NULL AS BIDNUMBER,
NULL AS BIDSTATUS,
h.userid,
h.accountid,
h.contactid,
h.opportunityid
INTO slxactivity
FROM [SalesLogix_Production].[sysdba].[activity] h
LEFT JOIN [SalesLogix_Production].[sysdba].[picklist] p
ON h.[type] = p.id
WHERE p.[text] NOT IN ( 'Personal Activity' )
AND Cast(h.startdate AS DATE) BETWEEN
#ReportStartDate AND #ReportEndDate
INSERT INTO slxactivity
SELECT ' Completed Activity:' + ' ' + p.[text] AS [TYPE],
h.createdate,
p.[text],
h.[description],
h.startdate,
h.completeddate,
NULL AS BIDNUMBER,
NULL AS BIDSTATUS,
h.userid,
h.accountid,
h.contactid,
h.opportunityid
FROM (SELECT accountid,
[description],
Min(historyid) AS HISTORYID,
completeddate
FROM [SalesLogix_Production].[sysdba].[history]
GROUP BY accountid,
[description],
completeddate) a1
LEFT JOIN [SalesLogix_Production].[sysdba].[history] h
ON a1.accountid = h.accountid
AND a1.historyid = h.historyid
LEFT JOIN [SalesLogix_Production].[sysdba].[picklist] p
ON h.[type] = p.id
WHERE p.[text] NOT IN ( 'Personal Activity' )
AND Cast(h.completeddate AS DATE) BETWEEN
#ReportStartDate AND #ReportEndDate
INSERT INTO slxactivity
SELECT 'Opportunity Added' AS [TYPE],
o.createdate,
o.status AS [TEXT],
NULL AS [DESCRIPTION],
o.estimatedclose AS STARTDATE,
NULL AS COMPLETEDDATE,
NULL AS BIDNUMBER,
NULL AS BIDSTATUS,
o.createuser,
o.accountid,
NULL AS CONTACTID,
o.opportunityid
FROM [SalesLogix_Production].[sysdba].[opportunity] o
WHERE Cast(o.createdate AS DATE) BETWEEN
#ReportStartDate AND #ReportEndDate
INSERT INTO slxactivity
SELECT 'Contact Added' AS [TYPE],
c.createdate,
NULL AS [TEXT],
NULL AS [DESCRIPTION],
NULL AS STARTDATE,
NULL AS COMPLETEDDATE,
NULL AS BIDNUMBER_STATIC,
NULL AS BID_STATUS,
c.createuser,
c.accountid,
c.contactid,
u.division,
NULL AS OPPORTUNITYID
FROM [SalesLogix_Production].[sysdba].[contact] c
LEFT JOIN [SalesLogix_Production].[sysdba].[userinfo] u
ON c.createuser = u.userid
LEFT JOIN [SalesLogix_Production].[sysdba].[usersecurity] us
ON u.userid = us.userid
WHERE Cast(c.createdate AS DATE) BETWEEN
#ReportStartDate AND #ReportEndDate
INSERT INTO slxactivity
SELECT 'Account Created' AS [TYPE],
a.createdate,
a.type AS [TEXT],
a.industry AS [DESCRIPTION],
NULL AS STARTDATE,
NULL AS COMPLETEDDATE,
NULL AS BIDNUMBER_STATIC,
NULL AS BID_STATUS,
a.createuser,
a.accountid,
NULL AS CONTACTID,
NULL AS OPPORTUNITYID
FROM [SalesLogix_Production].[sysdba].[account] a
WHERE Cast(a.createdate AS DATE) BETWEEN
#ReportStartDate AND #ReportEndDate
SELECT t.[type],
t.createdate,
t.[text],
u.username,
a.account,
c.lastname + ', ' + c.firstname AS [CONTACT],
o.[description] AS OPPORTUNITY,
oe.bidnumber_static,
oe.bid_status,
t.[description],
t.startdate,
t.completeddate,
u.division,
#ReportStartDate AS ReportStartDate,
#ReportEndDate AS ReportEndDate
FROM [SalesLogix_Production].[sysdba].[userinfo] u
JOIN [SalesLogix_Production].[sysdba].[usersecurity] us
ON u.userid = us.userid
LEFT JOIN slxactivity t
ON u.userid = t.userid
LEFT JOIN [SalesLogix_Production].[sysdba].[account] a
ON t.accountid = a.accountid
LEFT JOIN [SalesLogix_Production].[sysdba].[contact] c
ON t.contactid = c.contactid
LEFT JOIN [SalesLogix_Production].[sysdba].[opportunity] o
ON t.opportunityid = o.opportunityid
LEFT JOIN [SalesLogix_Production].[sysdba].[c_opportunity_ext] oe
ON t.opportunityid = oe.opportunityid
WHERE us.[type] NOT IN ( 'R', 'W' )
AND u.username <> 'svc_slxadmin'
You need to specify the column in the first statement which creates the table:
SELECT ' Current Activity:' + ' ' + p.[text] AS [TYPE],
h.createdate,
p.[text],
h.[description],
h.startdate,
Cast (NULL AS DATETIME) AS COMPLETEDDATE,
NULL AS BIDNUMBER,
NULL AS BIDSTATUS,
h.userid,
h.accountid,
h.contactid,
CAST(NULL AS VARCHAR(100)) AS division,
/*
you need to specify/select the column here, with the relevant
type, in this context. I assumed it's a string just for the example.
*/
h.opportunityid
INTO slxactivity
FROM [SalesLogix_Production].[sysdba].[activity] h
LEFT JOIN [SalesLogix_Production].[sysdba].[picklist] p
ON h.[type] = p.id
WHERE p.[text] NOT IN ( 'Personal Activity' )
AND Cast(h.startdate AS DATE) BETWEEN
#ReportStartDate AND #ReportEndDate