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