I have the following line of code that can either return one of 2 conditions ('Expired','Active'). I needed to use DATEDIFF to figure out the dates I needed.
However, now I need to alter this code so that I can add a sort of else if condition if neither of the 2 conditions are met and result to 'Unknown'.
I have this so far:
SELECT
IF(DATEDIFF(#endDate:=ADDDATE(h.StartDate,Interval h.NumMonth Month),NOW())<0,'Expired',
IF(DATEDIFF(#endDate,NOW())<120,'Expires in 120 days or less','Active')) AS bActive
FROM ...
So, for now, I have Expired, Active but I also want to include else 'Unknown' to be included as option. How would I alter this logic? Do I need to use ELSEIF or CASE? What should I use?
Use case instead of if. First, case is ANSI standard, so it works across databases. Second, it handles multiple conditions better. I think your logic is:
SELECT (CASE WHEN DATEDIFF(ADDDATE(h.StartDate, Interval h.NumMonth Month), NOW()) < 0
THEN 'Expired'
WHEN DATEDIFF(ADDDATE(h.StartDate, Interval h.NumMonth Month), NOW()) < 120
THEN 'Expires in 120 days or less'
ELSE 'Active'
END) AS bActive
Related
I have a query like this to get status without adding fields.
SELECT * ,
IF(DATEDIFF(STR_TO_DATE(end_date, "%Y-%m-%d"), CURDATE())<=0,"End","Running") status
FROM agreements
the query is running but I want to add status if the end date is less than 3 days then the status will show "will be ended"
so there will be 3 statuses in the query, END, RUNNING, Will be END
You can use CASE ..WHEN statements; also your STR_TO_DATE(end, '%Y-%m-%d') usage is unnecessary because DATEDIFF() function considers date part only for the calculation:
SELECT * ,
CASE WHEN DATEDIFF(end_date, CURDATE()) <= 0 THEN 'End'
WHEN DATEDIFF(end_date, CURDATE()) < 3 THEN 'Will Be End'
ELSE 'Running'
END status
FROM agreements
I am working on a Time Query with the following logic. But I am not familiar with time query. Can anyone help?
CASE WHEN (07:00:00) TO (07:10:00) is between [STARTTIME] AND [STOPTIME] THEN 'YES'
Start Time and Stop Time are both DateTime Field
Why not
CASE WHEN '07:00:00' >= [STARTTIME] AND '07:10:00' <= [STOPTIME] THEN 'YES'
if I understand clearly what you want to do.
HERE is the query :- I used #start_Time(for STARTIME) and #end_Time (for STOPTIME) as local variable you can replace them. (As you said between i am taking in between those values if you need to include those time too then instead of > you need to put >= and same with < replace with <=).
select CASE WHEN ((time_to_sec(timediff('07:00:00', time(#Start_Time))))>0
AND (time_to_sec(timediff('07:00:00', time(#end_Time))))<0)
AND
((time_to_sec(timediff('07:10:00', time(#Start_Time))))>0
AND (time_to_sec(timediff('07:10:00', time(#end_Time))))<0) =1
THEN 'YES' else 'NO' END
Hope it helps you !!
I am at the final stage of my project and have the problem to find if a job is overdue. I link this to priority for example if a job has a priority of 1 it must be complete in 1 day, a priority of 4 then 4 days.
I have come up with a CASE however this doesn't seem to work any help would be appreciated.
SELECT `defect_Id`,`Overtasked`
WHERE
CASE DATEDIFF(DD,`date_Investigaton` - `CURRENT_DATE()`) >= `priority` AS Overtasked
THEN `Overtasked` == 'YES'
ELSE `Overtasked` == 'NO'
END
Solution
`SELECT defect_Id,
CASE WHEN DATEDIFF(date_Investigated, CURDATE()) >= priority
THEN 'YES'
ELSE 'NO'
END AS Overtasked
FROM defect_report
WHERE defect_Id = '82'`
Appreciate the guidance you guys give!
You are completely mixing up SQL dialects and even there are syntax errors.
Assuming you are talking about MS SQL Server let's try this:
SELECT defect_Id,
CASE WHEN DATEDIFF(DD, date_Investigaton, getdate()) >= priority
THEN 'YES'
ELSE 'NO'
END AS Overtasked
FROM <YourTable>
WHERE <YourWhereIfAny>
If date_Investigation is a DATE column, the subtraction date_Investigation - CURRENT_DATE() produces the number of days you need.
Otherwise (if it is a DATETIME, for example) both operands are converted to float and the result is something you are totally not expecting. For such situations use the DATEDIFF() function. It interprets its arguments as DATE (ignores the time part) and returns the integer number of days between the two dates.
Your query should be like:
SELECT
`defect_Id`,
IF (DATEDIFF(`date_Investigaton`, CURRENT_DATE()) >= `priority`, 'YES', 'NO')
AS `Overtasked`
FROM [...your table name here...]
WHERE [...conditions...]
Replace the parts in square brackets ([...]) with the name of the table where to get the data from and some conditions to limit the number of returned rows (otherwise it will get the entire table which, most probably, is not what you want).
Btw, CURRENT_DATE() is also a function. If you write it in backquotes (``), MySQL will try to find a column with this name and it will fail.
Read the accepted answer for this question. It explains when to use back ticks, single quotes or double quotes in MySQL (and partially in PHP).
I am executing a query that obviously contains a subquery in MySQL.
Let me just jump into the code:
SELECT DATEDIFF(CURDATE(),
(SELECT due FROM checkOut JOIN People ON checkOut.p_id = People.p_id
WHERE CASE WHEN DATE_SUB(date_add(CURDATE(),INTERVAL 4 MONTH), INTERVAL 3 MONTH)
>= checkOut.checkTime THEN 1 ELSE 0 END ORDER BY checkOut.due)
);
The main query is the SELECT DATEDIFF(). Within that is my subquery which essentially searches through the table to look for items that are overdue based on an interval. I know that there will be multiple rows returned from the query and that it will not work with how I currently have it set up.
What I want are multiple values to be returned from my SELECT DATEDIFF(), so that I can loop through it with php later. To elaborate, I want each of the rows returned in the subquery to have an associated value from DATEDIFF(). How can I modify this query to do what I want? Or if anyone has a better method, please let me know.
Any help is appreciated.
In case you are wondering the why there is a DATE_ADD() within the DATE_SUB(), it is to simply make the query work for today.
get rid of the subquery, you can calculate the difference directly.
SELECT DATEDIFF(CURDATE(), due), due
FROM checkOut JOIN People
ON checkOut.p_id = People.p_id
WHERE CASE
WHEN DATE_SUB(date_add(CURDATE(),INTERVAL 4 MONTH), INTERVAL 3 MONTH)
>= checkOut.checkTime
THEN 1
ELSE 0
END
ORDER BY checkOut.due
Use the subquery as table. e.g. below:
SELECT DATEDIFF(CURDATE(), d.due)
FROM
(SELECT due FROM checkOut JOIN People ON checkOut.p_id = People.p_id
WHERE CASE WHEN DATE_SUB(date_add(CURDATE(),INTERVAL 4 MONTH), INTERVAL 3 MONTH)
>= checkOut.checkTime THEN 1 ELSE 0 END ORDER BY checkOut.due)
) AS d;
n00b questioner here. I'm trying to do a query that checks if the most recent activity is within the last 24 hours. I technically can get the result I want, but the inequality in my case statement has to be in the opposite direction as would make sense to me. Here's my query:
SELECT sqs.registration_id,
MAX(sqs.completed_at) AS 'most recent activity',
DATE_SUB(NOW(), INTERVAL 1 DAY) AS 'one day ago',
'recent activity?' = CASE
WHEN MAX(sqs.completed_at) <
DATE_SUB(NOW(), INTERVAL 1 DAY)
THEN 1
ELSE 0
END
FROM student_quiz_states sqs
WHERE sqs.score = 100
GROUP BY sqs.registration_id
Here's an example result:
XXXXX 2011-08-02 16:23:53 2011-12-05 00:06:05 0
This user did not have activity in the last 24 hours, so the last value returns 0, as I want it to.
However, that doesn't make any sense to me. Shouldn't the case statement return a 1, since the first datetime is much earlier than one day ago? It would make sense to me if my desired results were returned when my when_clause contained a > instead of a <.
Any explanations would be appreciated.
The problem is that your query contains 'recent activity?' = CASE ... END where it should have CASE ... END AS 'recent activity?'. The former is an equality-test rather than an expression with an alias. The reason for the seemingly "inverted" behavior is that, since the CASE expression is numeric (it evaluates to 0 or 1), MySQL performs a numeric equality-test, by converting 'recent activity?' to 0.0 (detailed rules here), such that 'recent activity?' = CASE ... END is true when the CASE expression gives 0 and false when it gives 1. Since MySQL represents true as 1 and false as 0, the end result is the opposite of what you were expecting.
(Note: An earlier version of this answer, while making the same basic point about equality-tests vs. aliases, and about false and true being 0 and 1, was vague/confused in other respects, since I didn't recognize that the DBMS was MySQL, and was not aware that some DBMSes allow single-quotes to be used when quoting aliases. So if some of the comments above and below seem a bit strange, it's because they're referring to that version. The current state of the answer is thanks in large part to those comments.)