How to make this time window query? - php

I have a MySQL table with the following columns:
id, month, day, remind_days_before
It's for a simple recurring reminder function. The user can enter for example: "I have a very important thing on the 5. April every year, please remind be 15 days before that". There could be tens of thousands of entries in this table. Using this table I want to run a cron_job every morning, which is sending out this reminders in form of email messages. The problem is I don't know how to write this kind of SQL query... Is it even possible? I want to query only those rows where the "month" and "day" as DATE is between TODAY and TODAY+31 days (this is the maximum number for remind_days_before).
I'm trying with this right now, but the $end_month is giving me the same as the $today_month:
$today_month = date('m');
$end_month = date('m', strtotime('+31 days', $today_month));
What happens when the +31 days DATE is in the next YEAR or we have leap year?!
Can someone help me out here?
Thank you very much.

First of all, your fields must be a no-mysql function.
So replace month/day with planning_month/planning_day, because the month and day words, are the functions of MySQL, and you may have errors if they are not quoted
Here's a working query. I've tested and works great:
select * from MyTable
/*CHECK CURRENT YEAR*/
where date(concat(year(now()), planning_month, planning_day)) =
date(date_add(now(), interval remind_days_before DAY))
OR
/*CHECK NEXT YEAR*/
date(concat(year(date_add(now(), INTERVAL 1 YEAR)), planning_month, planning_day)) =
date(date_add(now(), interval remind_days_before DAY))
Live Example
Your, it is a very useful question for me too

Just check for both years:
select *
from your_table
cross join (select year(now()) as current_year, year(now())+1 as next_year) vars
where curdate() + interval remind_days_before day = concat(current_year,'-',month,'-',day)
or curdate() + interval remind_days_before day = concat( next_year,'-',month,'-',day)

Related

Count current month from Database

i would like to count the date from the database where the month is now.
my code goes like
$sql="SELECT count(date) FROM tbl_upcoming where
date=MONTH(NOW())";
if ($results=mysqli_query($conn,$sql)){
$datecount=mysqli_num_rows($results);
}
for example: '2017-3-20', '2017-3-4', '2017-1-3', it will return 2.
Try something like this:
SELECT date, count(1) FROM tbl_upcoming where
MONTH(date)=MONTH(NOW()) and YEAR(date) = YEAR(NOW()) GROUP BY date
You were almost there:
SELECT count(*) FROM tbl_upcoming WHERE MONTH(the_date)=MONTH(NOW())";
The approach of MONTH(NOW()) is good, this will return you the current month.
However you were comparing the current month with a whole date, which can't work. You also have to apply the MONTH() function to your date to compare months with months
You should check like this,
month can be from past year or next year also,
select count(*) as cnt from tbl_upcoming
where MONTH(date) = MONTH(CURRENT_DATE) and YEAR(date) = YEAR(CURRENT_DATE);
I hope this will help.
You want to know how many rows are in the current month?
SELECT COUNT(*)
FROM tbl_upcoming
WHERE `date` >= CURDATE() - INTERVAL DAY(CURDATE())-1 DAY;
Notes:
In most situations, say simply COUNT(*).
CURDATE() is midnight this morning, hence easier to deal with for your query.
CURDATE() - INTERVAL DAY(CURDATE())-1 DAY gives you the DATE of the first of this month.
The formulation avoids all hiccups with various datatypes: DATE, DATETIME, DATETIME(6), TIMESTAMP, etc.
The next note handles leapdays, end of year, also.
If you have dates reaching into future months, then
add
AND `date` < CURDATE() - INTERVAL DAY(CURDATE())-1 DAY
+ INTERVAL 1 MONTH;

Extract records for 1 Week Time interval and Them start the next timer when the new week starts

I am using the query given below to extract the records for 1 Week Time interval.
mysql_query("SELECT t1.username, SUM(t2.points) AS total
FROM actcontest t2 JOIN user t1 ON t1.userid = t2.userid WHERE t2.date
BETWEEN (CURDATE() - INTERVAL 1 WEEK) AND CURDATE() GROUP BY t1.username ORDER BY
total DESC LIMIT 20");
Once the records are fetched I am using the different query to award bonuses to the top 3 users.
This works fine.
Problem:
Once bonus has been awarded to the last week, top 3 members, new dates shall start from the new week starting dates, where last week ended.
suppose: we started the timer on date: [dd/mm/yy]
Week 1 = {01-01-2010 to 07/01/2010}
Week 2 = {07-01-2010 to 14/01/2010}
Week 3 = {14-01-2010 to 21/01/2010}
Week 4 = {21-01-2010 to 28/01/2010}
Can you please help me in building this logic for my script.
I am using php and Mysql.
What I want to Do:
One i have awarded bonus to week one winners. I want timer to start fetching the members for the next week only, It should not include the previous dates .
I hope i clarified the question.
Consider something like this:
SET #weekNo := 4;
SET #dateStart := '2014-01-01';
SELECT ADDDATE(CONCAT(#dateStart, ' 00:00:00'), INTERVAL 7*(#weekNo-1) DAY),
ADDDATE(CONCAT(#dateStart, ' 23:59:59'), INTERVAL 7*#weekNo-1 DAY);
You can check the above script in sql. You can change the 2 variables at the top: #weekNo is the week you need to compute the date interval since the start date. And the #dateStart is the date the timer started.
In your php code you can compute the date by replacing the dateStart and weekNo with php variables.
select field1,field2
from table_name
where date_sub( field_date , INTERVAL 7 day) <= now()
see this you will get hint: https://stackoverflow.com/questions/26358240/show-data-from-the-last-7-days/26358454#26358454

Invoice query per 2 weeks. The best practice

I'm working on a invoice system for a application of mine. I want to invoice the users every 2 weeks. There is a cronjob every week with the check if the user gets an invoice. But it give me some bugs, because it has been a new year and the system gives someone a invoice even when they have got them a week ago.
This is my query:
SELECT *
FROM user
WHERE DAY(registered) = DAY(DATE_SUB(CURDATE(), INTERVAL 2 WEEK))
OR DAY(registered) = DAY(NOW()) AND registered != CURRENT_DATE()
Thank you!
You can try this- (code is tested) Demo
SELECT * FROM user WHERE registered > CURRENT_DATE() AND
MOD((FLOOR( DATEDIFF( now( ) , `registered` ))),14) = 0
The day function in MySQL returns the day of month. You will clearly have problems with your query when the time period spans month boundaries.
I think you want logic of this form:
SELECT *
FROM user
WHERE registered >= DATE_SUB(CURDATE(), INTERVAL 2 WEEK)) and
registered < curdate()
(Or <= if you want the current date to be invoiced.)
I do not know what this is doing:
OR DAY(registered) = DAY(NOW()) AND registered != CURRENT_DATE()
If the day of the month is the same for registered and now(), then registered should be the current date. The only difference between now() and curdate() is that the former includes the time stamp. I would also say that it is bad practice to mix three different ways of getting the same date in the same query, even if they are equivalent.

php mysql search birthday between two dates

I need to find the birth day of people from the table .. coming in next 7 days from today.
I have a query ..SELECT * FROMtableWHEREdobLIKE BETWEEN %-08-17 AND %-08-24 but it returns the records whose dates are not submitted in database..i mean the entry is 0000-00-00
I have stored the birthdates in dates format in table. Please Help me finding the bug.
Since this is mysql, I don't know if DATE_FORMAT() can work on this. But give this a try.
SELECT * FROM users WHERE DATE_FORMAT(dob, '%c-%d')
BETWEEN DATE_FORMAT('1983-08-17', '%c-%d')
AND DATE_FORMAT('1983-08-24', '%c-%d') OR (MONTH('1983-08-17') > MONTH('1983-08-24')
AND (MONTH(dob) >= MONTH('1983-08-17')
OR MONTH(dob) <= MONTH('1983-08-24')))
any year can be used (just to complete the date format) since year does not matter
UPDATE 1
Tested it on SQLFiddle.com
SQLFiddle Demo
UPDATE 2
I'm sorry for my first answer. I honestly missed to read this line coming in next 7 days from today. And I think that was the reason why I was downvoted by Imre L. He has his point. The reason why I posted the answer like that was because I thought the OP was asking for the days in between regardless of the year. So here is the update.
SELECT ....
FROM ....
WHERE DATE(dob) BETWEEN NOW() AND NOW() + INTERVAL 7 DAY
Hope it's clear now. :D
this will handle correctly cases wen there is a month or year change between the date range:
select *
from people
where (DAYOFYEAR(dob)+IF(DAYOFYEAR(CURDATE())>DAYOFYEAR(dob),1000,0))
between DAYOFYEAR(CURDATE())
and (DAYOFYEAR(CURDATE() + INTERVAL 7 DAY)+IF(DAYOFYEAR(CURDATE())>DAYOFYEAR(CURDATE() + INTERVAL 7 DAY),1000,0))
By converting the dob date into this year's date you can avoid issues where the period crosses a month or year boundary. This selects all rows where the birthdate occurs in the coming week:
SELECT * FROM users
WHERE concat( year(now()), mid(dob,5,6) )
BETWEEN now() AND date_add(now(), interval 7 day)
SELECT
str_to_date(DATE_ADD(dob, INTERVAL (YEAR(CURRENT_DATE()) - YEAR(dob)) YEAR), '%Y-%m-%d') BIRTHDAY,A.*
FROM app_membership A
WHERE str_to_date(DATE_ADD(dob, INTERVAL (YEAR(CURRENT_DATE()) - YEAR(dob)) YEAR), '%Y-%m-%d')
BETWEEN str_to_date('15-10-2017','%d-%m-%Y') and str_to_date('10-11-2017','%d-%m-%Y')
ORDER BY BIRTHDAY ASC;
Try this. Worked for me.
Lets list people who born in any month/year between december 14 and august 24. We know its an year before another one. We must count with months in the previous year. It's complex because you may have a problem comparing the month of the starting date with the month of the ending date. However, it may be solved with this query:
SELECT * FROM t_users WHERE (DATE_FORMAT(d_birth, '%m-%d')
BETWEEN DATE_FORMAT('2017-12-14', '%m-%d') AND
DATE_FORMAT('2018-08-24', '%m-%d'))
OR(MONTH('2017-12-31') >= MONTH('2018-08-24')
AND (MONTH(d_birth) >= MONTH('2017-12-31')
OR MONTH(d_birth) <= MONTH('2018-08-24')))

Getting an event from a database a week in advancee

I am currently developing a sports website where one of the pages with be forthcoming fixtures in which the user will be able to what team and where the team are playing their next match.
I have a database with the following fields...
ID
TEAM NUMBER
OPPOSITION
VENUE
DATE
MEET TIME
MATCH TYPE
So a row of data pulled from the DB and print_r'd may look like this
ID=>[1] TEAM NUMBER=>[1] OPPOSITION=>[YORKSHIRE] VENUE=>[HOME] DATE=>[2009/4/25] MEET TIME=>[13.00] MATCH TYPE=>[CUP]
My problem is i cannot work out how to show the next match dependent on what the current date is, so for example for now I want the site to show all the games that will happen over the weeken of the 25th April 2009 and then once that has gone the fixtures for the next weekend.
Hope this makes sense and some one give me an idea of how to tackle this.
select * from my_events where date between now() and date_add(now(), interval 7 day);
Should do it I think.
Instead of relying entirely on MySQL, you can also use PHP's strtotime() function:
$query = "select * from my_events where date between now() and ".
date("Y-m-d", strtotime("+1 week"));
For MySQL check out the Date and Time functions. You can use a combination of CURDATE() and ADDDATE() to achieve what you need.
Your description is very vage but try something like this:
SELECT all_fields_you_need
FROM table_name
WHERE `DATE` > CURDATE() AND `DATE` <= DATE_ADD(CURDATE(), INTERVAL 7 DAY)
ORDER BY `DATE` ASC
(not tested, just written as it came into my mind...)
Load it all into an array and display the data
you can get the system date (in Oracle using sysdate) and then add to it, so look for all records where DATE = sysdate + 7. You may have to play with this a little, formatting the date so that sysdate + 7 returns a date without the time, but that is basically what you need.
EDIT:
If you want the event between now and a week from now (if games are only on the weekend, then this will return next weekend's games) do
DATE > sysdate AND DATE <= sysdate + 7
To get the next match for team xxx
SELECT *
FROM myTable
WHERE TEAM NUMBER = xxx
AND DATE = ( SELECT MIN(DATE)
FROM myTable
WHERE TEAM NUMBER = xxx
AND DATE > NOW() )
I suspect this is what you really want, if matches only take place at weekends (which seems to be an assumption from your question).
Today + 7 days is not the same as next weekend unless today happens to be the same day of the week as the match.

Categories