DATEADD in MariaDB - sql

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.

Related

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

create fiscal week number

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.

Putting a word in the select statement

I want to put the word "days" after the value, but the sql server is reacting that it cannot be converted. How can I also not select the negative integers difference.
SELECT PONo, PODeliveryDate, DATEDIFF(DAY, GETDATE(), PODeliveryDate) AS DayDiff
FROM PurchaseOrder
where POStatus='Complete' OR POStatus='Partially Completed' OR POStatus='Approved'
ORDER BY ABS( DATEDIFF( DAY, GETDATE(), PODeliveryDate ))
It gives me the difference of dates, but I cannot put the word days beside it.
I want it to look like 5 days not just 5
Try to convert the int value from DATEDIFF() to varchar and add your word
SELECT PONo
, PODeliveryDate
, CAST(DATEDIFF(DAY, GETDATE(), PODeliveryDate) as varchar(10)) + ' days' AS DayDiff
FROM PurchaseOrder
WHERE POStatus='Complete'
OR POStatus='Partially Completed'
OR POStatus='Approved'
ORDER BY ABS( DATEDIFF( DAY, GETDATE(), PODeliveryDate ))
Convert this first DATEDIFF(DAY, GETDATE(), PODeliveryDate) into VARCHAR before you concatinate.
CONVERT(VARCHAR(50), DATEDIFF(DAY, GETDATE(), PODeliveryDate)) + 'days'
In sqlserver 2012, you can use CONCAT.
To only get the positive days, you can cast getdate as date and compare with that in the WHERE statement. Then you dont need to order by ABS datediff.
The WHERE clause is easier to read and maintain by using IN instead of OR, it also makes is easier to maintain.
SELECT
CONCAT(DATEDIFF(DAY, GETDATE(), PODeliveryDate), ' days') AS DayDiff
FROM
PurchaseOrder
WHERE
POStatus in ('Complete','Partially Completed','Approved')
AND CAST(GETDATE() as date) <= PODeliveryDate
ORDER BY
PODeliveryDate
Can you try like as follow:
select CONVERT(varchar(10), GETDATE()) + ' Days'
You need to convert or cast into varchar before concate

SQL replace using SELECT and invalid column

I have a simple table where the date column answer_6 (formatted as varchar(max) either has a valid date or string Now. I wanted to substitute the Now with the current date/time and then calculate the difference. Here is what I did:
select
CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END as x,
answer_6 from [tDataMult] where DATEDIFF(yy, GETDATE(), [x]) > 5
The system give me invalid column name 'x'. If I remove the DateDiff SELECT statement works fine.
You can't use aliases in the WHERE clause of the same level as it was defined as WHERE clause is evaluated before the SELECT clause. Try the following :
SELECT t.* FROM (<...>) t WHERE DATEDIFF(yy, GETDATE(), [t.x]) > 5
Instead <...> put your query without WHERE clause.
You can't refer to an alias you've just created in a WHERE clause. The easiest way to fix it would just be to turn your original query into a subquery:
SELECT *
FROM
(
select
CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END as x,
answer_6 from [tDataMult]
) AS qry
WHERE DATEDIFF(yy, GETDATE(), [x]) > 5
Or you could replicate the expression in your WHERE clause:
select
CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END as x,
answer_6 from [tDataMult]
WHERE DATEDIFF(yy, GETDATE(),
(CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END)
) > 5
Column X does not exist in tDataMult table because it is an alias.
Replace it with answer_6 in DateDiff function.
However, one of the possible value of answer_6 column is varchar format ('Now').
You need to have valid data format to use DATEDIFF function properly. (for example: 'yyyy-mm-dd').

"CASE" statement within "WHERE" clause in SQL Server 2012

i have a select statement like this
select x, y , z from table a
where CAST( CAST(DATEColumn AS VARCHAR) AS DATE) between
case when a.columnx = '1900-01-01' then CAST( CAST(DATEColumn AS VARCHAR) AS DATE) else c.columnx end
and cast( c.CustomerShipToRecTrmDt as date)
why does this case statement does not work
whereas the case statement works if i hardcode the dates?
What are you casting a date columns to varchar and then back to a date? I think this does what you want:
select x, y , z
rom table a
where DATEColumn between
(case when a.columnx = '1900-01-01' then DATEColumn else cast(c.columnx as date) end and
cast( c.CustomerShipToRecTrmDt as date)
You can eliminate the case statement from the where clause by doing:
where DATEColumn >= cast(c.columnx as date) and DateColumns <= cast( c.CustomerShipToRecTrmDt as date)
The comparison to 1900-01-01 doesn't affect the >= part, unless you are working with dates before 1900 (I'm guessing this is unlikely).
Also, whenever casting values to varchar(), always include the length (as in varchar(255)).