I want to put 0 instead of negative values from DATEDIFF - sql

The table with the following structure is considered:
MEDICINE: (name, price, quantity, expiration_date );
I did
SELECT Name,
DATEDIFF(expiration_date, CURRENT_DATE)
AS days
FROM MEDICINE;
I got negative results from datediff, but I want to put 0 instead of the negative values. How can I make this? Any help?

Try this:
SELECT Name
, CASE
WHEN DATEDIFF(expiration_date, CURRENT_DATE) < 0 THEN 0
ELSE DATEDIFF(expiration_date, CURRENT_DATE)
END AS days
FROM MEDICINE;
Unfortunately you have to repeat the expression, but the engine should be smart enough to only calculate it once.

You can use GREATEST() in combination with a - because DATEDIFF() doesn't exist in PostgreSQL:
SELECT Name,
GREATEST(expiration_date - CURRENT_DATE, 0)
AS days
FROM MEDICINE;

This should work for you.
GREATEST(0, DATEDIFF(expiration_date, CURRENT_DATE))
Read about these conditional operators here. Spend some time reading about the suite of functions and operators in your SQL language: it's time well spent.

You can do it using SQL case.
This should work:
SELECT Name,
CASE WHEN DATEDIFF(expiration_date, CURRENT_DATE) > 0 THEN DATEDIFF(expiration_date, CURRENT_DATE)
ELSE 0
END
AS days
FROM MEDICINE;
You can read more about it here: https://www.w3schools.com/sql/sql_case.asp

Related

Teradata Current year and year-1

How to get the dynamic years in the Query for where condition, i need to fetch data for 2017,2018,2019, currently i am hard coding them ( where FSC_YR in (2017,2018,2019) instead i need in a dynamic way. How to do it in teradata.
I tried extract(year from current_date)-2,extract(year from current_date)-1,extract(year from current_date)-3). I am getting error too many expression.
Since you're looking for a range of year numbers, why not just use a BETWEEN?
SELECT *
FROM data
WHERE fsc_yr BETWEEN EXTRACT(year FROM current_date - interval '2' year) AND EXTRACT(year FROM current_date)
But as #dnoeth pointed out in the comments.
To avoid an error when running it on Feb. 29, using INTERVAL might not be the safest method.
But just subtracting from the year number isn't so bad really.
SELECT *
FROM data
WHERE fsc_yr BETWEEN EXTRACT(year FROM current_date)-2 AND EXTRACT(year FROM current_date)
Also note that such error can come from selecting more than 1 column in the query for an IN
For example this would fail:
SELECT * FROM Table1
WHERE Col1 IN (SELECT Col1, Col2 FROM Tabel2)
So if you would use the query for data with a * then it would still result in that error.

SQL Select DATES and assign accordingly

I'm using SQL Oracle;
I want to do the following operation, if the YEAR on the column is equal to my current year then I want to assign the value of 0 to a new column called ano, and if it's a year ahead than current year then I want it to be 1 and so on, if it's less than the current year then I want it to be -1 and so on.
The column name that contains the date is KALW_DATE
SELECT *,
CASE
WHEN YEAR(KALW_DATE) > YEAR(NOW()) THEN (YEAR(KALW_DATE) - YEAR(NOW()))
WHEN YEAR(KALW_DATE) < YEAR(NOW()) THEN (YEAR(KALW_DATE) + YEAR(NOW())
ELSE 0
END as ano
FROM tablename;
but I get an error saying "keyword FROM not found where expected" also I'm connecting to DB2, if that changes anything.
You seem to just want:
SELECT (YEAR(KALW_DATE) - YEAR(NOW())) as ano
As for your code, the parentheses do not balance in the second THEN clause.
Oracle does not have a YEAR() function (at least not the version I'm running). You have to use the EXTRACT() function, like this:
SELECT *,
(extract(year from KALW_DATE) - extract(year from current_date)) as ano
FROM tablename;

Can DATE_PART be used in HAVING clause?

When the following SQL query is executed, it seems that the HAVING clause doesn't take any effect.
SELECT
day_of_week,
fc,
gl,
CASE WHEN COUNT(inbound_allocation_factors) IS null THEN 0 ELSE count(inbound_allocation_factors) END AS num_of_factors,
DATE(request_datetime) AS date
FROM
allocationworkflow_with_gl
GROUP BY day_of_week,fc,gl,date
HAVING day_of_week = DATE_PART(dw,MAX(request_datetime))
request_datetime is a timestamp, and day_of_week is integer from 0 to 6 indicating Sunday to Saturday. By the way, I'm using Redshift. Could anyone help me? Many thanks!
Your problem is not datepart(). Your problem is the day_of_week with no aggregation. You can validate this by doing:
HAVING DATE_PART(dw, MAX(request_datetime)) = 1
I'm not sure what you really want to do, but this answers your immediate question.

Not getting actual minutes in SQL DateDiff

I searched in different places and found below queries. I am using the following queries to get the actual minutes difference in SQL. The dates I provide are the same day. I need difference in minutes only but SQL is returning 35 instead of 5 minutes in the first query. And the second query return milliseconds.
SELECT DATEDIFF(MINUTE,GETDATE(), CONVERT(datetime,'2016-08-11 16:04:24'))%3600/60 AS MinuteDiff
SELECT datediff(minute,GETDATE(), CONVERT(datetime,'2016-08-11 16:04:24')) as MinutesDiff
What is missing. Please help.
I need to put a condition that if time is less than 20 minutes then
do this
else
do this
Updated:
The issue occurs when i use GetDate(). When I use a fix date it works fine
You need to place the GETDATE() after your datetime value, other wise in your case you will get the minutes in negative value.
SELECT DATEDIFF(MINUTE,CONVERT(datetime,'2016-08-11 16:04:24'), GETDATE()) AS MinuteDiff
The current GETDATE() is 2016-08-11 17:05:39.053, so it returns 61.
Then based on the value, using IF ... ELSE ... you can do your expected operation:
IF DATEDIFF(MINUTE,CONVERT(datetime,'2016-08-11 16:04:24'), GETDATE()) < 20
PRINT 'With in 20 mins'
ELSE
PRINT 'More than 20 mins'
Here is a working example of what your after...although you probably need to switch out the date components as appropriate for your usage.
select
case
when
(SELECT datediff(minute,GETDATE(), CONVERT(datetime,'2016-08-11 06:00:00'))) < 20 then
(select 'do this')
else
(select 'do something else')
end as answer
If you want minute span between two datetime, then your second one is enough.
SELECT datediff(n, CONVERT(datetime,'2016-08-11 16:04:24'),GETDATE()) as MinutesDiff
you can use CASE for your further
select
case when
datediff(n, CONVERT(datetime,'2016-08-11 16:04:24'),GETDATE()) < 20 then
`your code`
else
`your else code`
end minte
Hey sorry for the initial poor explanation.
I use something like the following frequently this will return a INT and decide if it's then you can do the logic on it, equal to, not equal less than greater than etc.
If it is true it will return a 1 or it is false a 0. You can get it to return columns or set it to a string.
Hope it helps
select
Case
When DateDiff(minute,[column],Getdate()) > 20 then 1 else 0
end as [alias]

Invalid Operation On An ANSI DATETIME (Subtracting one timestamp from another in Teradata)

I would like to create a WHERE condition to return results where only 1 day has passed between two timestamps. I tried this:
SELECT * FROM RDMAVWSANDBOX.VwNIMEventFct
INNER JOIN VwNIMUserDim ON VwNIMUserDim.NIM_USER_ID = VwNIMEventFct.NIM_USER_ID
INNER JOIN rdmatblsandbox.TmpNIMSalesForceDB ON TmpNIMSalesForceDB.EMAIL = VwNIMUserDim.USER_EMAIL_ADDRESS
WHERE (CONTRACT_EFFECTIVE_DATE - EVENT_TIMESTAMP) =1
But the result was an error message "Invalid Operation On An ANSI DATETIME value".
I guess that, looking at the code now, Teradata has no way of knowing whether the "1" in "= 1" is a day, hour or year.
How would I select data where only 1 day has passed between CONTRACT_EFFECTIVE_DATE and EVENT_TIMESTAMP?
Same again for 2 days, and 3 days etc?
If both columns are DATEs you can use =1which means one day.
For Timestamps you need to tell what kind of interval you want:
WHERE (CONTRACT_EFFECTIVE_DATE - EVENT_TIMESTAMP) DAY = INTERVAL '1' DAY
But i'm not shure if this is what you really want, what's your definition of 1 day?
Edit:
Based on your comment the best way should be:
WHERE CAST(CONTRACT_EFFECTIVE_DATE AS DATE) - CAST(EVENT_TIMESTAMP AS DATE) = 1
This avoids dealing with INTERVAL arithmetic :-)
Not sure about Teradata, but I think most versions of SQL have built-in date math functions. In MSSQL for instance you could do this:
...
WHERE DATEDIFF(DAY, CONTRACT_EFFECTIVE_DATE, EVENT_TIMESTAMP) = 1
Or if you wanted to make sure 24 hours had passed you could do:
...
WHERE DATEDIFF(HOUR, CONTRACT_EFFECTIVE_DATE, EVENT_TIMESTAMP) = 1
Other SQL's have their own versions of this, and you may have to use 'D' or 'DD' instead of 'DAY' or something (and maybe 'HH' instead of 'HOUR' likewise).