Select depending CURDATE MySQL - mysql

I have the following query:
SELECT tbl_usuarios.Correo,
tbl_alertas.Id,
tbl_alertas.Purpose,
tbl_alertas.Status,
tbl_alertas.OpenDate,
tbl_alertas.CloseDate,
tbl_alertas.Owner,
tbl_alertas.ValueStream,
tbl_alertas.Family
FROM tbl_usuarios
INNER JOIN tbl_alertas ON tbl_usuarios.Nombre = tbl_alertas.Owner
WHERE (STATUS = 'En aprobacion' OR STATUS = 'Activa')
AND CloseDate < CURDATE()
As a result of this query I have the following table:
Everything it's ok.
Now, the problem is that I 'm going to use that query in my website, I create a JavaScript function which is going to be executed every 5th and every 19th of a month. My question, what can I do to only select the row which his CloseDate is <= yyyy-mm-07 or CloseDate >= yyyy-mm-07 and <= yyyy-mm-21 depending of CURDATE(5th or 19th), example:
Curdate = yyyy-mm-05.
Expected result: Data from Id 00003
What I tried was adding another AND to the query, something like this:
AND CloseDate < CURDATE() AND CloseDate <= '2016-09-07'
If my question is not much clear let me explain with this, I want to select CloseDate '2016-09-07' when curdate = '2016-whatever-05, 06', 07 or select CloseDate '2016-09-21' where curdate = '2016-whatever-19, 20, 21'.

Don't know if I understood your problem correctly but check the DAYOFMONTH() or simply DAY() function.
Returns the day of the month for date, in the range 1 to 31, or 0 for
dates such as '0000-00-00' or '2008-00-00' that have a zero day part.
You can use it like this
SELECT tbl_usuarios.Correo,
tbl_alertas.Id, tbl_alertas.Purpose,
tbl_alertas.Status, tbl_alertas.OpenDate,
tbl_alertas.CloseDate,
tbl_alertas.Owner,
tbl_alertas.ValueStream,
tbl_alertas.Family
FROM tbl_usuarios
INNER JOIN tbl_alertas
ON tbl_usuarios.Nombre = tbl_alertas.Owner
WHERE (STATUS = 'En aprobacion' OR STATUS = 'Activa')
AND (CASE
WHEN DAY(CURDATE()) = '5' AND DATE(CloseDate) <= DATE_FORMAT(NOW() ,'%Y-%m-07')
THEN 1
WHEN DAY(CURDATE()) = '19' AND (DATE(CloseDate) >= DATE_FORMAT(NOW() ,'%Y-%m-07') AND DATE(CloseDate) <= DATE_FORMAT(NOW() ,'%Y-%m-21'))
THEN 1
ELSE 0
END)

Related

MySQL Query Comparing DateTime not give the right row

dosen_schedule_datetimestart , dosen_schedule_datetimeend , academic_schedule_datetimestart , academic_schedule_datetimeendis formatted in DATETIME Format YYYY-MM-DD HH:MM:SS
This was my MySQL Query, so what i want to do is SELECT Row that Today is still in between datetimestart and datetimeend And TIME of datetimestart is less than 15 minutes compared to current time
But it doesnt work, and i also comparing academic_schedule_dow with Today's DOW
Any Idea?
$checkdosenschedule = mysqli_query($conn, "SELECT dosen_schedule_table.*, dosen_table.*, TIME(dosen_schedule_table.dosen_schedule_datetimestart) AS dosen_schedule_checkstart FROM dosen_schedule_table
INNER JOIN dosen_table
ON dosen_table.dosen_id = dosen_schedule_table.dosen_id
WHERE (dosen_schedule_status = 'Active' AND dosen_subs_id != '' ) AND ((DATE(dosen_schedule_datetimestart) >= CURDATE() AND DATE(dosen_schedule_datetimeend) >= CURDATE()) AND (TIME(dosen_schedule_datetimestart) > (NOW() - INTERVAL 15 MINUTE)))");
$checkacademicschedule = mysqli_query($conn, "SELECT academic_schedule_table.*, dosen_table.* FROM academic_schedule_table
INNER JOIN dosen_table
ON dosen_table.dosen_id = academic_schedule_table.dosen_id
WHERE ((academic_schedule_status = 'Active' AND dosen_subs_id != '' ) AND academic_schedule_dow = DAYOFWEEK(NOW())) AND ((DATE(academic_schedule_datetimestart) >= CURDATE() AND DATE(academic_schedule_datetimeend) >= CURDATE()) AND (TIME(academic_schedule_datetimestart) > (NOW() - INTERVAL 15 MINUTE)))");
Try using DATE(NOW()) instead of CURDATE()
Also you are checking the range with same sign of greater then equal to.
If you want to check in between, use >= for start and <= for end.

MySQL TIME() BETWEEN datetime issue

I'm trying to find to which shift belongs a datetime field.
Shifts are defines as time, and I have a startingHour and endingHour.
The query
SELECT * FROM shifts WHERE TIME('2009-11-20 06:35:00') BETWEEN '06:00:00' and '19:00:00'
works perfect, but when the shift is set to start 19:00:00 to 06:00:00 and the time is 23:35:00 it doesn't return anything
WHERE TIME('2009-11-20 23:35:00') BETWEEN '19:00:00' and '06:00:00'
that line isn't returning anything though I do have records on the table
Thanks
That's the shifts table.
if I query this:
SELECT
a.ID,
b.Nombre
FROM turnos a
JOIN operarios b ON a.oID = b.oId
WHERE a.uId = 1
AND (TIME('2019-11-22 18:23:00') BETWEEN a.horaInicio AND a.horaFin )
LIMIT 1
I get the proper result, but when I query this:
SELECT
a.ID,
b.Nombre
FROM turnos a
JOIN operarios b ON a.oID = b.oId
WHERE a.uId = 1
AND (TIME('2019-11-22 02:45:00') BETWEEN a.horaInicio AND a.horaFin )
LIMIT 1
I get no result.
These are two cases: start time < end time and start time > end time. You need something like this:
where (start_time < end_time and $t >= start_time and $t < end_time)
or (start_time >= end_time and ($t < start_time or $t >= end_time))
Since '19:00:00' is greater than '06:00:00' then:
BETWEEN '19:00:00' and '06:00:00'
returns 0 (false) and you get no rows.
One way to get the results that you want is to use CASE like this:
.................
AND 1 = CASE
WHEN a.horaInicio <= a.horaFin THEN TIME('2019-11-22 02:45:00') BETWEEN a.horaInicio AND a.horaFin
ELSE (TIME('2019-11-22 02:45:00') BETWEEN a.horaInicio AND '23:59:59')
OR (TIME('2019-11-22 02:45:00') BETWEEN '00:00:00' AND a.horaFin)
END

SQL query from time_in column but not from time_out column

I'm using mysql. I have a table time_record. There are four columns namely id, time_in, time_out and students_id. I only want to query the record of the latest time_in of the student but if the latest record of the student is in time_out, it will not query. How do I query the student's latest time_in record if given that the student still does not times out?
Thanks
Here is my sample code (though it returns both records from timein and timeout)
select concat (
st.student_fname,
' ',
st.student_lname
) as 'Name',
t.students_id,
t.time_in,
t.time_out,
case
when t.time_in > t.time_out
then t.time_in
else t.time_out
end as MostRecentDate
from classes c
join student_classes s on c.id = s.classes_id
join timerecords t on t.students_id = s.students_id
join students st on s.students_id = st.student_id
where c.employees_id = 'sessionvalue2'
and
where date (t.time_in) between date (now()) and date (now())
From what I understand, you want to query all results in which time_in is the latest entry and exclude results where time_out is the latest entry.
Try this:
SELECT DISTINCT(tr.id), tr.time_in
FROM time_record tr
WHERE tr.time_in > tr.time_out
ORDER BY tr.time_in DESC
I think your time_out columns may have nulls due to which the comparison results in false in that case and it return time_out.
Also,
date (t.time_in) between date (now()) and date (now())
doesn't make any sense. If you want to check the time_in for today's date, do:
date(t.time_in) = curdate();
Use curdate() instead of date(now()).
or Sargable so that index can be used if any:
date >= curdate()
and date < date_add(curdate(), interval 1 day)
Try flipping the condition like this:
select concat (
st.student_fname,
' ',
st.student_lname
) as 'Name',
t.students_id,
t.time_in,
t.time_out,
case
when t.time_in < t.time_out
then t.time_out
else t.time_in
end as MostRecentDate
from classes c
join student_classes s on c.id = s.classes_id
join timerecords t on t.students_id = s.students_id
join students st on s.students_id = st.student_id
where c.employees_id = 'sessionvalue2'
and date >= curdate()
and date < date_add(curdate(), interval 1 day)

MySql Query string date issue

I have this query string here ($month = 11):
select * from members where CURDATE() = DATE_ADD(renewal_date, INTERVAL $month MONTH);
What this query string will do is get all my members with a renewal_date from 11 months ago from the current date
I also have two other fields, reminder_date and blocker. What I am looking to add is, to get members with a reminder_date from 1 month ago from the current date and if the blocker is not equal to 1 (blocker can be 0 or 1)
How would I do that?
Thanks,
J
You can try this:
SELECT *
FROM members
WHERE CURDATE() = DATE_ADD(renewal_date, INTERVAL $MONTH MONTH)
OR (
CURDATE() = DATE_ADD(reminder_date, INTERVAL 1 MONTH)
AND blocker = 0
);
This will get your original results and add the ones with reminder_date of one month ago and blocker = 0

Is this possible with mysql?

First of all: sorry for the title, but maybe I will find a better one later.
I asked this some minutes ago, but since I was not able to describe what I want I try it again :)
Here is my table structure:
http://sqlfiddle.com/#!2/b25f9/37
The table is used to store user sessions.
Out of this I would like to generate a stacked bar chart that should show how many active users I have. My idea was that I group the users based on their online-times of the last days like this
Lets say its friday:
Group B: Users that were online thursday (and today)
Group C: Users that were not online thursday but wednesday (and today)
Group D: Users that were not online thursday or wednesday but tuesday (and today)
Group E: Users that were not online thursday, wednesday or tuesday but last monday, sunday or saturday (and today)
Group A: Users that do not match the other groups (but were only today)
I only want to know the number of users in those groups (for a specific day)
a user can only be in ONE of these groups (for the same day)
Another Update: Accidently (by copy&paste) had starttime = ... or starttime = ... but it should be starttime = ... or endtime = ...
UPDATE:
To explain my query in more detail (in the final query there are even more comments):
First we simply got
SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
That's nothing more like saying "give me all users whose session started today or ended today". Having to consider those two times again and again makes the query a bit clumsy, but actually it's not that complicated.
So, usually we would use the COUNT() function to count something, obviously, but since we want "conditional counting", we simply use the SUM() function and tell it when to add 1 and when not.
SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name
The SUM() function examines now each row in the result set of sessions from today. So for each user in this result set we look if this user was online the date we specify. It doesn't matter how many times he/she was online, so for performance reasons we use EXISTS. With EXISTS you can specify a subquery which stops as soon as something is found, so it doesn't matter what it returns when something is found, as long as it's not NULL. So don't get confused why I selected 1. In the subquery we have to connect the user which is currently examined from the outer query with the user from the inner query (subquery) and specify the time window. If all criterias meet count 1 else 0 like explained before.
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterday,
Then we make a column for each condition and voila, you have all you need in one query. So with your updated question your criteria has changed, we just have to add more rules:
SELECT
/*this is like before*/
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndThursday,
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 2 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 2 DAY)))
/*this one here is a new addition, since you don't want to count the users that were online yesterday*/
AND NOT EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndWednesdayButNotThursday,
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 3 DAY) /* minus 3 days to get tuesday*/
OR (date(endtime) = CURDATE() - INTERVAL 3 DAY)))
/*this is the same as before, we check again that the user was not online between today and tuesday, but this time we really use BETWEEN for convenience*/
AND NOT EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndTuesdayButNotThursdayAndNotWednesday,
.../*and so on*/
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
So, I hope you get the idea now. Any more questions? Feel free to ask.
end of update
Answer to previous version of question:
select
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterday,
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterdayOrTheDayBeforeYesterday,
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndWithinTheLastWeek
from gc_sessions s
where date(starttime) = CURDATE()
or date(endtime) = CURDATE()
Instead of relying on session table, I suggest you to create separate table, which stores 2 fields, date and user_id.
Every time user logs-in you need to insert new entry into this table.
This way you will be able to retrieve all the 3 requirement of yours.
Example table:
CREATE TABLE `test`.`user_login_history` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`userid` INTEGER UNSIGNED NOT NULL,
`date` DATETIME NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;
Once a user login, check whether he/she has login today or not:
select count(*) from user_login_history where
userid = 1 and `date` = '2013-01-28 00:00:00';
If the returned value is 1, means he/she has login today. no changes needed.
but, if the returned value is 0, means he/she has not login today. So record it down.
insert into user_login_history(userid,`date`)values(1,'2013-01-28 00:00:00');
Q1. How many users were online TODAY that were also online YESTERDAY?
select count(*) from user_login_history u where
u.`date` = '2013-01-28 00:00:00' and
(
select count(*) from user_login_history v where
v.`date` = '2013-01-27 00:00:00' and
v.userid = u.userid
) = 1;
Q2. How many users were online TODAY that were also online within in the last TWO DAYS
select count(*) from user_login_history u where
u.`date` = '2013-01-28 00:00:00' and
(
select count(*) from user_login_history v where
v.`date` >= '2013-01-26 00:00:00' and
v.`date` <= '2013-01-27 00:00:00' and
v.userid = u.userid
) > 0;
Q3. How many users were online TODAY that were also online within the last 7 DAYS
select count(*) from user_login_history u where
u.`date` = '2013-01-28 00:00:00' and
(
select count(*) from user_login_history v where
v.`date` >= '2013-01-21 00:00:00' and
v.`date` <= '2013-01-27 00:00:00' and
v.userid = u.userid
) > 0;
For yesterday
select id from gc_sessions where id in
(
select id
from gc_sessions
where starttime > subdate(current_date, 2)
and endtime < subdate(current_date, 1)
)
and starttime > subdate(current_date, 1);
For 2 Days
select id from gc_sessions where id in
(
select id
from gc_sessions
where starttime > subdate(current_date, 3)
and endtime < subdate(current_date, 1)
)
and starttime > subdate(current_date, 1);
For 7 Days
select id from gc_sessions where id in
(
select id
from gc_sessions
where starttime > subdate(current_date, 8)
and endtime < subdate(current_date, 1)
)
and starttime > subdate(current_date, 1);
You need to add a subquery that loads the data from the specified range (eg, 1day/2day/7days) and compares it with the data for the current day.
set #range = 7;
select * from gc_sessions
WHERE user in (SELECT user from gc_sessions
where starttime between subdate(current_date, #range) AND subdate(current_date, 1))
AND starttime > subdate(current_date, 0)
Where #range holds information about the number of days. See your expanded sql fiddle at - http://sqlfiddle.com/#!2/9584b/24
SELECT today.user
, GROUP_CONCAT(DISTINCT today.ip) ip
FROM gc_sessions today
JOIN gc_sessions yesterday
ON DATE(yesterday.starttime) = DATE(today.starttime) - INTERVAL 1 DAY
AND today.user = yesterday.user
WHERE DATE(today.starttime) = '2013-01-10'
GROUP
BY today.user;