Update Column using calculation in last year from another table - sql-server

I am trying to update (using Inner joins for three tables) item stats STAT for table IM_ITEM by highlighting items that sold less than 12 as "D" (Discontinue).
The 2nd table PS_TKT_HIST_LIN has the Quantity sold column QTY_SOLD for each item on each day and the date column BUS_DAT.
I also need a third table IM_INV to filter the data, I need to say the last received date LST_RECV_DAT for these items is earlier than "2019-01-01" and last sales date LST_SAL_DAT is after "2019-01-01". I used the following code
UPDATE M
SET M.STAT = 'D'
FROM
dbo.IM_ITEM AS M
INNER JOIN
IM_INV AS N
ON
M.ITEM_NO = N.ITEM_NO
INNER JOIN
dbo.PS_TKT_HIST_LIN S`
ON
M.ITEM_NO = S.ITEM_NO
WHERE
CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, N.LST_RECV_DAT))) <= '2019-01-01'
AND CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, N.LST_SAL_DAT))) >= '2019-01-01'
AND M.STAT = 'A'
AND SUM(case when DATEPART(YYYY, (BUS_DAT)) = DATEPART(YYYY, DATEADD(YYYY, -1, getdate()))
AND DATEPART(yyyy, (BUS_DAT)) = DATEPART(yyyy, DATEADD(YYYY, -1, getdate()))
then qty_sold else 0)<12
It comes with an error
Any advise please

You should use HAVING clause instead of Sum in where.
You can use CTE to achieve the value, then update accordingly.
;with cte as(
select ITEM_NO, ..
from ..
group by ITEM_NO
having .. < 12
)
update M
set SET M.STAT = 'D'
from dbo.IM_ITEM AS M
inner join cte on M.ITEM_NO = cte.ITEM_NO

You can't use an aggregate function in where clause unless defined under subquery.

Related

Return a zero value if there is no data found

I am trying to create a query to pull the number of new clients/week over 3 months. In the weeks where there was no new customers, it doesn't return anything - I would like it to return a zero value. I understand I need to create a table of all the possible weeks. But I am having trouble understanding how to create the table and join it.
SELECT distinct COUNT(DISTINCT dbo.Quotes.qmpQuoteID) AS "Qty of Quote Lines Won",
MIN(OmpOrderDate) As "WeekStarting"
FROM SalesOrders
Left Outer Join SALESORDERLINES On OMPSALESORDERID = OMLSALESORDERID
Left Outer Join QUOTELINES On OMLQUOTEID = QMLQUOTEID And OMLQUOTELINEID = QMLQUOTELINEID
Left Outer Join QUOTES On QMLQUOTEID = QMPQUOTEID left outer join organizations on dbo.Quotes.qmpCustomerOrganizationID = dbo.Organizations.cmoOrganizationID
WHERE ompOrderDate >= DATEADD(MOnth, -3, GETDATE())
AND cmocustomerprospectdate >= DATEADD(MOnth, -3, GETDATE())
AND OMLQUOTEID > 1
Group By DATEADD(week, DATEDIFF(week, 0, ompOrderDate),0)
Order by MIN(OmpOrderDate) ASC
Thanks in advance!
this returns the results :
Qty of Quote Lines Won Week Starting
1                           23/04/2020
1                           15/05/2020
2                           19/05/2020
1                           etc
2
Ideally this would look like:
Qty of Quote Lines Won Week Starting
1                            21/04/2020
0                           28/04/2020
0                           05/05/2020
1                           12/05/2020
etc - many thanks - I'm sorry my formatting is terrible

Is there a way to loop a query using a distinct list of values with the way I have written this?

I have written a query that I currently have hardcoded to filter by department. This entire query works the way I want it and I could copy/paste this query dozens of times and write all results to a temp table but I would like a simpler and more dynamic solution. Is there some way I can loop by the distinct results of FullDepartmentFacilityName from my Forecast table? I have a few other areas in this code that are also hard coded that need to be the same value.
'ABC.ALLXYZ' is what I have to hard code
====================================================
SELECT *
FROM
[clc].[ForecastTable]
WHERE
FullDepartmentFacilityName = 'ABC.ALLXYZ'
and
DateColumn = CAST(GETDATE() AS DATE)
and
(
(ROUND (PopCountForecast, 0) > (SELECT MAX(ACT.PopCountActual)
FROM
clc.ActualTable ACT
JOIN [dim].[DepartmentTable] DTD
ON DTD.DeptID = ACT.DeptId
JOIN [dim].[FacilityTable] FD
ON FD.FclID = ACT.FclID
WHERE
ACT.DateColumn >= DATEADD(DAY, -28, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, ACT.DateColumn) = DATEPART(WEEKDAY, GETDATE())
and CONCAT(FD.FclName,'.All',DTD.DeptName) = 'ABC.ALLXYZ'))
or
(ROUND (PopCountForecast, 0) < (SELECT MIN(ACT.PopCountActual)
FROM
clc.ActualTable ACT
JOIN [dim].[DepartmentTable] DTD
ON DTD.DeptID = ACT.DeptID
JOIN [dim].[FacilityTable] FD
ON FD.FclID = ACT.FclID
WHERE
ACT.DateColumn >= DATEADD(DAY, -28, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, ACT.DateColumn) = DATEPART(WEEKDAY, GETDATE())
and CONCAT(FD.FclName,'.All',DTD.DeptName) = 'ABC.ALLXYZ'))
)
Table Structure
clc.ForecastTable - this is the main table for my query. this table has one column with a concatenated facility/department name I am calling FullDepartmentFacilityName. This table has forecasted Population Counts by facility/department key by day.
Example:
FullDepartmentFacilityName PopCountForecast Date
ABC.ALLAAA 10 7/16/19
ABC.ALLBBB 5 7/16/19
ABC.ALLCCC 8 7/16/19
BCA.ALLAAA 9 7/16/19
BCA.ALLBBB 4 7/16/19
BCA.ALLCCC 9 7/16/19
"dim.DepartmentTable" - this has all department IDs and their corresponding names
"dim.FacilityTable" - this has all facility IDs and their corresponding names
"clc.ActualTable" - this table contains real data and has a facility column and department column but not a concatenated facility/department column. This is why I created one in my query.
Have you tried CROSS APPLY? You don't give the table structure, so I can only guess what the table structure.
SELECT *
FROM (
SELECT DISTINCT FullDepartmentFacilityName
FROM Forecast
) d
CROSS APPLY (
SELECT *
FROM [clc].[ForecastTable]
WHERE FullDepartmentFacilityName = d.FullDepartmentFacilityName
and DateColumn = CAST(GETDATE() AS DATE)
and (
(ROUND (PopCountForecast, 0) > (
SELECT MAX(ACT.PopCountActual)
FROM clc.ActualTable ACT
JOIN [dim].[DepartmentTable] DTD ON DTD.DeptID = ACT.DeptId
JOIN [dim].[FacilityTable] FD ON FD.FclID = ACT.FclID
WHERE ACT.DateColumn >= DATEADD(DAY, -28, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, ACT.DateColumn) = DATEPART(WEEKDAY, GETDATE())
and CONCAT(FD.FclName,'.All',DTD.DeptName) = 'ABC.ALLXYZ')
) or (
ROUND (PopCountForecast, 0) < (
SELECT MIN(ACT.PopCountActual)
FROM clc.ActualTable ACT
JOIN [dim].[DepartmentTable] DTD ON DTD.DeptID = ACT.DeptID
JOIN [dim].[FacilityTable] FD ON FD.FclID = ACT.FclID
WHERE ACT.DateColumn >= DATEADD(DAY, -28, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, ACT.DateColumn) = DATEPART(WEEKDAY, GETDATE())
and CONCAT(FD.FclName,'.All',DTD.DeptName) = 'ABC.ALLXYZ')
)
)
) c

SQL Server: SUM amount when date greater than eomonth

I have a view that returns this result.
I want to sum the amounts where dateValidite is great then a certain end of month (that changes)
For example last day of month is '2016/01/31' so I will sum all the amounts (MontantAuto) where DateValidite > last day of month
I'm using this query but this sum I get is incorrect
select
a.Monnaie
, a.Category
, a.Personne
, EOMONTH(DATEADD(mm,-1,a.DateValidite)) as Previous
, sum(b.MontantAuto) As mnt
from
olap.tf_autorisation_balance a
inner join
olap.tf_autorisation_balance b on a.Id = B.Id
where
EOMONTH(DATEADD(mm,-1,a.DateValidite)) < b.DateValidite
group by
a.Monnaie, a.Category, a.Personne, a.DateValidite
Change your request as :
where EOMONTH(DATEADD(mm,-1,a.DateValidite)) < CONVERT(VARCHAR(10), b.DateValidite, 103)

15 days before today in SQL Server

I am trying to find the list of specific job # from load date in our database with the specific condition and I have to use inner join as well.
i want to have last 15 days worth of Job # in my store procedure.
How do I set up the LoadDate that will change auto for last 15 days only.
Here is my query:
select pr.Job_Number,
Count(ItemCode1) as [Total Records],
si.PackageComplete
from
processed_record pr
inner join scanner_2 si on pr.ItemCode1 = si.ItemCode1
where
pr.Format_Name like '%Lin%' and pr.LoadDate >= '03/01/2016'
group by
pr.Job_Number, si.PackageComplete
order by
si.PackageComplete, pr.Job_Number
Your query should be as follow:
select pr.Job_Number,
Count(ItemCode1) as [Total Records],
si.PackageComplete
from
processed_record pr
inner join scanner_2 si on pr.ItemCode1 = si.ItemCode1
where
pr.Format_Name like '%Lin%' and pr.LoadDate >= DATEADD(DAY,-15,GETDATE())
group by
pr.Job_Number, si.PackageComplete
order by
si.PackageComplete, pr.Job_Number
GETDATE() will get the current date and DATEADD() function will add (subtract) -15 days.
You could use
CONVERT(date, DATEADD(DAY, -15, GETDATE()))
insted your fix Date Value.
With this code you recieve the current Date GetDate() and substract 15 Days DateAdd(day, -15, DateValue)
Finaly you Convert it into Date Typ Convert(date, value) otherwise you would get the current time, too.

how to calculate date range in sql using interval

I have a two tables in one table I have a column contravention date and in other table i have NTO date column
now I want to find how can I retrieve data from tables where NTOdate is greater than 50 days of contravention date.
but when I run this query i get error as Incorrect syntax near '50'.
SELECT [ICPS].[dbo].[tickets].t_vrm
,[ICPS].[dbo].[tickets].t_zone_name
,[ICPS].[dbo].[tickets].t_street_name
FROM [ICPS].[dbo].[tickets]
INNER JOIN [ICPS].[dbo].[ticket_events]
ON [ICPS].[dbo].[ticket_events].[te_system_ref] = [ICPS].[dbo].[tickets].[t_number]
WHERE [ICPS].[dbo].[tickets].[t_camera_ticket] = '0'
AND [ICPS].[dbo].[tickets].[t_date_time_issued] >= convert(DATETIME, '2012/10/01', 101)
AND [ICPS].[dbo].[ticket_events].[te_event_code] = '300'
AND [ICPS].[dbo].[ticket_events].[te_date] > DATE (DATE_SUB([ICPS].[dbo].[tickets].[t_date_time_issued], INTERVAL 50 days))
You can use Datediff function: DateDiff(DD,'firstDate','SecondDate'). Here is the sample:
select [ICPS].[dbo].[tickets].t_vrm,[ICPS].[dbo].[tickets] .t_zone_name, [ICPS].[dbo].[tickets] .t_street_name from [ICPS].[dbo].[tickets] inner join
[ICPS].[dbo].[ticket_events] on [ICPS].[dbo].[ticket_events].[te_system_ref] = [ICPS].[dbo].[tickets].[t_number]
where[ICPS].[dbo].[tickets].[t_camera_ticket] = '0' and [ICPS].[dbo].[tickets].[t_date_time_issued] >= convert(datetime,'2012/10/01',101)
and [ICPS].[dbo].[ticket_events].[te_event_code] = '300' and
DateDiff(DD, [ICPS].[dbo].[tickets].[t_date_time_issued], [ICPS].[dbo].[ticket_events].[te_date]) >50)

Resources