create fiscal week number - sql

How can I put the below logic into a format SQL Server will use to create a fiscal week number ?
if (datepart(week,getdate())-4) <= 0 then (datepart(week,getdate())+49) else (datepart(week,getdate())-4)

The CASE Statement should work:
CASE
WHEN (datepart(week,getdate())-4) <= 0
THEN datepart(week,getdate())+49
ELSE
datepart(week,getdate())-4
END

You could use a case expression:
SELECT CASE WHEN (DATEPART(WEEK, getdate()) - 4) <= 0
THEN DATEPART(WEEK, getdate()) + 49
ELSE DATEPART(WEEK, getdate()) - 4
END

For SQL Server 2012+, you can use IIF
SELECT IIF((datepart(week, getdate())-4) <= 0, datepart(week, getdate()) + 49, datepart(week, getdate()) - 4 )
For Less than SQL Server 2012 version, you may use CASE.

Related

How to query all rows that are due the next business day?

If it helps, I'm using BytePro which I believe is using T-SQL based on the statement they've generated.
I'm having an issue where when I try retrieving data, I need to switch based on the day of the week. (current day being today's date using GetDate()).
M-T statement:
convert(varchar(10), [Status.SchedFundingDate], 112) <= convert(varchar(10), getdate() + 1, 112)
F statement:
convert(varchar(10), [Status.SchedFundingDate], 112) <= convert(varchar(10), getdate() + 3, 112)
I'd like to combine the two to automate the switch but I get a problem with
CAST(CASE
WHEN DATENAME(DW, GETDATE()) = 'Friday'
AND [Status.SchedFundingDate] <= GETDATE() + 3
THEN 1
WHEN [Status.SchedFundingDate] <= GETDATE() + 1
THEN 1
ELSE 0
END AS BIT)
I get an error:
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'
this is the right syntax :
CAST(CASE WHEN DATENAME(DW, GETDATE()) = 'Friday'
AND [Status].[SchedFundingDate] <= DATEADD(DAY, 3 , GETDATE())
THEN 1
WHEN [Status].[SchedFundingDate] <= DATEADD(DAY, 1 , GETDATE())
THEN 1
ELSE 0
END AS BIT)
db<>fiddle here

DATEADD in MariaDB

I'm using DATEADD statement in SQL Server and I need migration to MariaDB
SUM (
CASE
WHEN CONVERT(varchar, Production.MadeDate , 112) BETWEEN DATE_ADD(DAY, -2, '2018-06-05') AND DATE_ADD(DAY, -2, '2018-06-05') THEN
Production.Qty
ELSE
0
END
) AS 'N-2'
And i got error like this
[42000][1064] You have an error in your SQL syntax; check the manual
that corresponds to your MariaDB server version for the right syntax
to use near 'varchar, Production.MadeDate , 112) BETWEEN DATE_ADD(DAY,
-2, '2018-06-05') AND ' at line 3
I'm got references from MariaDB DATE_ADD and MariaDB ADDDATE but it's still doesn't working
My Version MariaDB 10.1.32-MariaDB
EDIT :
[SOLVED]
Changing the SQL Statment from CONVERT to CAST
SUM (
CASE
WHEN CONVERT(varchar, Production.MadeDate , 112) BETWEEN DATE_ADD(DAY, -2, '2018-06-05') AND DATE_ADD(DAY, -2, '2018-06-05') THEN
Production.Qty
ELSE
0
END
) AS 'N-2'
TO
SUM (
CASE WHEN CAST(Production.MadeDate AS DATE) BETWEEN DATE_ADD('2018-06-05', INTERVAL -2 DAY) AND DATE_ADD('2018-06-05', INTERVAL -2 DAY) THEN
Production.Qty
ELSE
0
END
) AS 'N-2'
It's working for me on
10.1.32-MariaDB
You can't use the CONVERT like this on MariaDB / MySQL:
CONVERT(varchar, Production.MadeDate, 112)
The order of the parameters isn't valid on MariaDB / MySQL. The order of the parameters looks like TSQL / SQL Server syntax.
So you can replace the current CONVERT with one of the following:
CONVERT(Production.MadeDate, DATE) -- using CONVERT (ODBC syntax)
CAST(Production.MadeDate AS DATE) -- using CAST (SQL92 syntax)
You can use the following SUM using CAST and DATE_ADD:
SUM (
CASE WHEN CAST(Production.MadeDate AS DATE) BETWEEN DATE_ADD('2018-06-05', INTERVAL -2 DAY) AND DATE_ADD('2018-06-05', INTERVAL -2 DAY) THEN
Production.Qty
ELSE
0
END
) AS 'N-2'
Note: Check the condition on CASE WHEN also. You check between the same days.
In no database should you be converting date/time values to strings for comparison. I also discourage the use of BETWEEN. So, I would expect something like this in MariaDB:
SUM(CASE WHEN Production.MadeDate >= '2018-06-05' - INTERVAL 2 DAY AND
Production.MadeDate < '2018-06-05' - INTERVAL 1 DAY
THEN Production.Qty
ELSE 0
END) AS N_2
In SQL Server, I would write this as:
SUM(CASE WHEN Production.MadeDate >= DATEADD(day, -2, '2018-06-05') AND
Production.MadeDate < DATEADD(day, -1, '2018-06-05')
THEN Production.Qty
ELSE 0
END) AS N_2
Note the changes:
All comparisons are done using native date/time types.
The N-2 is changed to N_2, so the column alias does not need to be escaped.
The date/time comparisons are made using direct comparisons, rather than BETWEEN.

SQL Find/Ignore invalid date

I am using SQL Server.
From each row, I take day and month values from the fields c.daybirth,c.monthbirth
and the year from getdate(), and I want to have a field that shows if this date is valid or not (invalid example: 31 February)
I have created this solution:
case day(dateadd(month,c.monthbirth-1,dateadd(day,c.daybirth-1,DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)))) when c.daybirth then 1 else 0 end
which works, but I find it hard to read. Is there a smarter alternative?
In SQL Server 2012+, you can do:
where try_convert(date,
datefromparts(year(getdate()), c.monthbirth, c.daybirth)
) is not null
EDIT:
Amusing. This is better:
where try_convert(date,
cast(year(getdate()) * 10000 + c.monthbirth * 100 + c.daybirth as varchar(255))
) is not null

Improvise SQL query

I have the below sql which takes 1 or 2 secs to return the result. I am calling this SQL inside cursor for 500 plus times. I am trying to re-write this query.
SELECT Sum(CASE
WHEN UpdatedAdjustedOT IS NOT NULL
AND UpdatedAdjustedOT != ''
AND UpdatedAdjustedOT != '0'
THEN CONVERT(DECIMAL(18, 2), UpdatedAdjustedOT)
ELSE 0
END) AS OTHours
FROM tbl_OTAuthorization
WHERE EmployeeCodeFK = #EmployeeCode
AND month(OTDate) = Month(#FromDate)
AND year(OTDate) = Year(#FromDate)
Please suggest me how do I re-write this query in a better way
Don't filter on function results. Find a way to replace this:
AND month(OTDate) = Month(#FromDate)
AND year(OTDate) = Year(#FromDate)
to something like this:
and OTDate >= the first day of the month for #FromDate
and OTDate < the first day of the month following #FromDate
First, re-write the WHERE clause to look like this:
SELECT . . .
FROM tbl_OTAuthorization
WHERE EmployeeCodeFK = #EmployeeCode AND
OTDate >= DATEADD(day, 1 - DAY(#FromDate), #FromDate) AND
OTDate < DATEADD(month, 1, DATEADD(#FromDate, 1 - DAY(#FromDate), #FromDate));
Second, create an appropriate index for the table:
CREATE INDEX tbl_OTAuthorization_2 ON tbl_OTAuthorization(EmployeeCodeFK, OTDate, UpdatedAdjustedOT);
Third, go back and fix your code so it is not looping over employees and from dates. You should be able to handle the logic in a single query. In general, avoid cursors if you want to optimize the performance of using a database.
Try this:
SELECT Sum(CONVERT(DECIMAL(18, 2), ISNULL(NULLIF(UpdatedAdjustedOT, ''), 0))) as OTHours
FROM tbl_OTAuthorization
WHERE EmployeeCodeFK = #EmployeeCode
AND month(OTDate) = Month(#FromDate)
AND year(OTDate) = Year(#FromDate)
WHERE EmployeeCodeFK = #EmployeeCode
AND OTDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, #FromDate), 0)
AND OTDate < DATEADD(MONTH, 1, DATEADD(MONTH, DATEDIFF(MONTH, 0, #FromDate), 0))

SQL Dynamic Column Reuse

I have the following SQL statement:
Select
DateAdd(month, 1, DateField) as MyNewDate,
CASE WHEN MyNewDate < GetDate() THEN 0 ELSE 1 END as Expired
End
I would like to reuse the calculation in the DateAdd without reevaluating the DateAdd for the Expired column. In reality the query is a lot more complex than this simple dateAdd.
The error I get is :
Invalid column name 'MyNewDate'.
How can I reuse the dynamic column?
You can't use an alias in the same query.
You need something like this
SELECT MyNewDate, CASE WHEN MyNewDate < GetDate() THEN 0 ELSE 1 END as Expired
FROM
(
Select DateAdd(month, 1, DateField) as MyNewDate...
)
or retype it like
Select
DateAdd(month, 1, DateField) as MyNewDate,
CASE WHEN DateAdd(month, 1, DateField) < GetDate() THEN 0 ELSE 1 END as Expired
End
SELECT MyNewDate,
CASE WHEN MyNewDate < GetDate() THEN 0 ELSE 1 END as Expired
(
Select
DateAdd(month, 1, DateField) as MyNewDate
FROM tab
)