Use IF statement within a calulated field - sql

I am trying to determine all sales within the current financial year and wanted to incorporate an If statement as a calculated field to do so. Please see my code below.
SELECT RtnUserId, COUNT(*) AS Returns_, RtnDt, COUNT(RtnDt) AS DtRet,
IF
BEGIN
YEAR(RtnDt) = YEAR(GETDATE()) AND MONTH(RtnDt) >= 4
RETURN 'INDATE'
END as Financial_Period
FROM dbo.vw_AN_Admin_VendorReturns
WHERE (RtnUserId = 'BEND1') OR
(RtnUserId = 'DEENA') OR
(RtnUserId = 'RICHARDK2')
GROUP BY RtnUserId, RtnDt,
IF
BEGIN
YEAR(RtnDt) = YEAR(GETDATE()) AND MONTH(RtnDt) >= 4
RETURN'INDATE'
END

Related

Move Functions from Where Clause to Select Statement

I have a union query that runs abysmally slow I believe mostly because there are two functions in the where clause of each union. I am pretty sure that there is no getting around the unions, but there may be a way to move the functions from the where of each. I won't post ALL of the union sections because I don't think it is necessary as they are all almost identical with the exception of one table in each. The first function was created by someone else but it takes a date, and uses the "frequency" value like "years, months, days, etc." and the "interval" value like 3, 4, 90 to calculate the new "Due Date". For instance, a date of today with a frequency of years, and an interval of 3, would produce the date 4/21/2025. Here is the actual function:
ALTER FUNCTION [dbo].[ReturnExpiration_IntervalxFreq](#Date datetime2,#int int, #freq int)
RETURNS datetime2
AS
BEGIN
declare #d datetime2;
SELECT #d = case when #int = 1 then null-- '12-31-9999'
when #int = 2 then dateadd(day,#freq,#date)
when #int = 3 then dateadd(week,#freq,#date)
when #int = 4 then dateadd(month,#freq,#date)
when #int = 5 then dateadd(quarter,#freq,#date)
when #int = 6 then dateadd(year,#freq,#date)
end
RETURN #d;
The query itself is supposed to find and identify records whose Due Date has past or is within 90 days of the current date. Here is what each section of the union looks like
SELECT
R.RequirementId
, EC.EmployeeCompanyId
, EC.CompanyId
, DaysOverdue =
CASE WHEN
R.DueDate IS NULL
THEN
CASE WHEN
EXISTS(SELECT 1 FROM tbl_Training_Requirement_Compliance RC WHERE RC.EmployeeCompanyId = EC.EmployeeCompanyId AND RC.RequirementId = R.RequirementId AND RC.Active = 1 AND ((DATEDIFF(DAY, R.DueDate, GETDATE()) > -91 OR R.DueDate Is Null ) OR (DATEDIFF(DAY, dbo.ReturnExpiration_IntervalxFreq(TRC.EffectiveDate, R.IntervalId, R.Frequency), GETDATE()) > -91)) OR R.IntervalId IS NULL)
THEN
DateDiff(day,ISNULL(dbo.ReturnExpiration_IntervalxFreq(TRC.EffectiveDate, R.IntervalId, R.Frequency), '12/31/9999'),getdate())
ELSE
0
END
ELSE
DATEDIFF(day,R.DueDate,getdate())
END
,CASE WHEN
EXISTS(SELECT 1 FROM tbl_Training_Requirement_Compliance RC WHERE RC.EmployeeCompanyId = EC.EmployeeCompanyId AND RC.RequirementId = R.RequirementId AND RC.Active=1 AND (GETDATE() > dbo.ReturnExpiration_IntervalxFreq(RC.EffectiveDate, R.IntervalId, R.Frequency) OR R.IntervalId IS NULL))
THEN
CONVERT(VARCHAR(12),dbo.ReturnExpiration_IntervalxFreq(TRC.EffectiveDate, R.IntervalId, R.Frequency), 101)
ELSE
CONVERT(VARCHAR(12),R.DueDate,101)
END As DateDue
FROM
#Employees AS EC
INNER JOIN dbo.tbl_Training_Requirement_To_Position TRP ON TRP.PositionId = EC.PositionId
INNER JOIN #CompanyReqs R ON R.RequirementId = TRP.RequirementId
LEFT OUTER JOIN tbl_Training_Requirement_Compliance TRC ON TRC.EmployeeCompanyId = EC.EmployeeCompanyId AND TRC.RequirementId = R.RequirementId AND TRC.Active = 1
WHERE
NOT EXISTS(SELECT 1
FROM tbl_Training_Requirement_Compliance RC
WHERE RC.EmployeeCompanyId = EC.EmployeeCompanyId
AND RC.RequirementId = R.RequirementId
AND RC.Active = 1
)
OR (
(DATEDIFF(DAY, R.DueDate, GETDATE()) > -91
OR R.DueDate Is Null )
OR (DATEDIFF(DAY, dbo.ReturnExpiration_IntervalxFreq(TRC.EffectiveDate, R.IntervalId, R.Frequency), GETDATE()) > -91))
UNION...
It is supposed to exclude records that either don't exist at all on the tbl_Training_Requirement_Compliance table, or if they do exist, once the frequency an intervals have been calculated, would have a new due date that is within 90 days of the current date. I am hoping that someone with much more experience and expertise in SQL Server can show me a way, if possible, to remove the functions from the WHERE clause and help the performance of this stored procedure.

Make a case with several results SQL TERADATA

I am looking to make a case in a SQL query and assign according to the condition several results.
For example :
Code :
INSERT INTO DESTINATION_TABLE (DT_TRT, NU_QUARTER, NU_YEAR) VALUES
(SELECT
CASE
WHEN #P_DT_TRT# = '1900-00-00'
THEN MAX(TT.DT_CTTT)
ELSE #P_DT_TRT#
END AS DT_TRT,
CASE
WHEN EXTRACT (MONTH FROM DT_TRT) < 4
THEN NU_QUARTER = 4 AND NU_YEAR = EXTRACT (YEAR FROM DT_TRT) - 1
ELSE NU_YEAR = EXTRACT (YEAR FROM DT_TRT)
END
CASE
WHEN EXTRACT (MONTH FROM DT_TRT) < 7
THEN 1
ELSE (CASE WHEN EXTRACT (MONTH FROM DT_TRT) < 10 THEN 2 ELSE 3 END AS NU_QUARTER)
END AS NU_QUARTER
FROM TARGET_TABLE TT);
Algorithm :
-> A date will be given in the programme to enable the calculation (#P_DT_TRT#)
If the parameter is not supplied (value = 1900-00-00)
DT_TRT = the largest constitution date (DT_CTTT) in the target table (TARGET_TABLE TT)
Otherwise DT_TRT = date given in parameter
If DT_TRT month < 4
Quarter = 4
Year = Year of DT_TRT - 1
Otherwise Year = Year of DT_TRT
If DT_TRT month < 7
Quarter = 1
Otherwise
If DT_TRT < 10
Quarter = 2
Otherwise Quarter = 3
Question : Is it possible to integrate several results (DT_TRT, NU_QUARTER, NU_YEAR) in one case ? And if so, what is the syntax ?
I work in Teradata Studio.
Thank you for your answers. :)
This seems to be your logic:
INSERT INTO DESTINATION_TABLE (DT_TRT, NU_QUARTER, NU_YEAR)
VALUES
(
-- If the parameter is not supplied (value = 1900-00-00)
-- DT_TRT = the largest constitution date (DT_CTTT) in the target table (TARGET_TABLE TT)
-- Otherwise DT_TRT = date given in parameter
CASE
WHEN #P_DT_TRT# = '1900-00-00'
THEN (SELECT Max(DT_CTTT) FROM TARGET_TABLE)
ELSE #P_DT_TRT#
END,
-- shift back year/quarter by three months to adjust for company's business year
td_quarter_of_year(Add_Months(DT_TRT, -3)),
Extract(YEAR From Add_Months(DT_TRT, -3))
)
;

Use Case Statement Based on input Parameters in Sql server

I have need to apply certain logic in one of our stored procedures.
We have a parameter #season in the sp.
If #season = 0, then i have to entire years budget value.
if #season = 1, then i have to take tax-season budget values
if #season = 2, then i have to take pre-season budget values.
i derived startdate and enddate of each season
as #SeasonStrt , #SeasonEnd
#SeasonStart is from January 1 to April 30 and #SeasonEnd from May 1 to December 30
I have tried something like below,
SELECT SUM(ISNULL(lab.BudgetAmt,0)),
SUM(ISNULL(lab.ProjectedHours,0))
FROM [dbo].[Budget] bud
WHERE [Year] = #taxyear
AND ((#season = 0) OR (Season= #season))
AND CASE WHEN #season in (1,2)
THEN bud.[week] >= CASE WHEN #season in (1,2)THEN #SeasonStrt ELSE bud.[week] END
AND bud.[week] <= CASE WHEN #season in (1,2)THEN #SeasonStrt ELSE bud.[week] END
Sql server gives syntax error. What will be solution which meets my requirement?
thanks for the help
Try this:
SELECT SUM(ISNULL(lab.BudgetAmt,0)),
SUM(ISNULL(lab.ProjectedHours,0))
FROM [dbo].[Budget] bud
WHERE [Year] = #taxyear
AND
(
((#season = 0) AND (Season = #season))
OR ((#season = 1) AND (bud.[week] >= #SeasonStrt))
OR ((#season = 2) AND (bud.[week] <= #SeasonStrt))
)
So, idea is simple: combine your conditions with OR and specific #season value

SQL To Track Rules

I am using MS SQL Server and have a stored procedure where I evaluate transactions based on certain rules and mark each row as eligible or not based on these rules. For example, a transaction from prior year is ineligible, certain products may not be eligible.
I also want to record the reason why the transaction is ineligible. For example, from prior year, ineligible product, etc. I have a table that lists all ineligibility codes.
I apply rules sequentially and record the first reason for ineligibility in the field eligCode defined as int.
But I cannot seem to figure out how to code this in the stored procedure. Any help would be greatly appreciated. Thanks in advance.
This should give you head start:
CREATE PROCEDURE [dbo.YourSprocName]
AS
BEGIN
SELECT CASE
WHEN datepart(year, transaction_date) = datepart(year, getdate()) - 1 --if transaction_date year = previous year
THEN 'Ineligible'
WHEN product_type = < something > -- non eligible products
THEN 'Non-eligible'
ELSE 'Eligible'
END AS transaction_status
,CASE
WHEN ineligibility_code = 1 -- assuming 1 is one of the ineligbility code
THEN 'Bad transaction'
ELSE 'Unknown'
END AS ineligibilty_reason_desc
FROM YourTable
WHERE yourColumn = < condition >
END
declare #eligCode as int
declare #TransID as int
....
select #TransID = NNN -- some value declared above
#eligCode = CASE
WHEN YEAR(TRANSACTION_DATE) < YEAR(getdate()) THEN 1
WHEN [CONDITION2] THEN 2
WHEN [CONDITION3] THEN 3
WHEN [CONDITION4] THEN 4
ELSE 0
END
...
Insert into LOG_TABLE (Transaction_ID, eligCode) values (#TransID, #eligCode)

How to add check for January in SQL statement

I'm creating a report using SQL to pull logged labor hours from our labor database for the previous month. I have it working great, but need to add logic to prevent it from breaking when it runs in January. I've tried adding If/Then statements and CASE logic, but I don't know if I'm just not doing it right, or if our system can't process it. Here's the snippet that pulls the date range:
SELECT
...
FROM
...
WHERE
...
AND
YEAR(ENTERDATE) = YEAR(current date) AND MONTH(ENTERDATE) = (MONTH(current date)-1)
Just use AND as a barrier like this. In January, the second clause will be executed instead of the first one:
SELECT
...
FROM
...
WHERE
...
AND
(
(
(MONTH(current date) > 1) AND
(YEAR(ENTERDATE) = YEAR(current date) AND MONTH(ENTERDATE) = (MONTH(current date)-1))
-- this one gets used from Feb-Dec
)
OR
(
(MONTH(current date) = 1) AND
(YEAR(ENTERDATE) = YEAR(current date) - 1 AND MONTH(ENTERDATE) = 12)
-- alternatively, in Jan only this one gets used
)
)
If your report is always going to be for the previous month, then I think the simplest idea is to declare the year and month of the previous month and then reference those in the Where clause. For example:
Declare LastMo_Month Integer = MONTH(DATEADD(MONTH,-1,getdate()));
Declare LastMo_Year Integer = YEAR(DATEADD(MONTH,-1,getdate()));
Select ...
Where MONTH(EnterDate) = #LastMo_Month
and YEAR(EnterDate) = #LastMo_Year
You could even take it a step further and allow the report to be created for any number of months ago:
Declare Delay Integer = -1;
Declare LastMo_Month Integer = MONTH(DATEADD(MONTH,#Delay,getdate()));
Declare LastMo_Year Integer = YEAR(DATEADD(MONTH,#Delay,getdate()));
Select ...
Where MONTH(EnterDate) = #LastMo_Month
and YEAR(EnterDate) = #LastMo_Year
Hope this helps.
PS - This is my first answer on StackOverflow, so sorry if the formatting isn't right!
if(month(getdate()) = 1)
begin
your jan logic
end
else
begin
your logic
end
The above answer with the Case is ok, but running a CASE on a huge result set would be pretty costly
WHERE
...
AND
DATEPART(yy,ENTERDATE) = DATEPART(yy,DATEADD(m,-1,ENTERDATE))
AND DATEPART(m,ENTERDATE) = DATEPART(m,DATEADD(m,-1,ENTERDATE))
Which Dialect of SQL are you speaking?
As opposed to doing it all with case statements, just use the built it date / time functions to subtract a month from the current date, which should handle crossing year boundaries.
TransACT
WHERE
YEAR(ENTERDATE) = year(dateadd(MONTH,-1, CURRENT_TIMESTAMP))
AND MONTH(ENTERDATE) = month(dateadd(MONTH,-1, CURRENT_TIMESTAMP))
Mysql
WHERE
YEAR(ENTERDATE) = YEAR(date_sub(curdate(),INTERVAL 1 MONTH))
AND MONTH(ENTERDATE) = MONTH(date_sub(curdate(),INTERVAL 1 MONTH) )
Try adding the previous month and year to your SELECT statement:
SELECT
...
,CASE MONTH(current date)
WHEN 1 THEN 12
ELSE MONTH(current date)-1
END AS previous_month
,CASE MONTH(current date)
WHEN 1 THEN YEAR(current date)-1
ELSE YEAR(current date)
END AS previous_year
FROM
...
WHERE
...
AND YEAR(ENTERDATE) = previous_year
AND MONTH(ENTERDATE) = previous_month
This should allow you to set the value before the WHERE comparison. This should be the most performant way to perform this procedure, as it avoids creating two entirely separate clauses or using OR.