I'm a WordPress (PHP) developer, however I have not done a lot of complex MySQL queries. I am working on an events website and want to create filters: User should be able to filter events by the following criteria: TODAY, TOMORROW, THIS WEEKEND, NEXT 7 DAYS, CHOOSE YOUR DATES.
Meta data used to filter events is below and can be found in the post meta db table in the meta_key column.
start_date
end_date
times
recurring_event
days
sold_out
cancelled
This is how the table looks like:
id post_id meta_key meta_value
1 12 start_date 20140923
2 22 days a:4:{i:0;s:6:"monday";i:1;s:9:"wednesday";i:2;s:6:"friday";i:3;s:8:"saturday"}
3 12 end_date 20141003
4 78 recurring_event 0
5 34 times 24 Hours
6 12 days a:2:{i:0;s:6:"monday";i:1;s:7:"tuesday";}
7 67 start_date 20140906
8 45 end_date 20141108
What MySQL queries can I use to get events for Today, Tomorrow, Weekend and 7 days.
I do not know SQL enough, then, for this case, I would caculate the date with PHP and then make the query with SQL.
These are the pages that helped me for the following :
http://php.net/manual/fr/function.date.php
http://php.net/manual/fr/function.mktime.php
1) For today, no calculation, just get the date of today and make the query :
<?php
$today = date('Y-m-d',mktime());
$result = mysqli_query($connect, 'SELECT * FROM events WHERE start_date = "'.$today.'"');
?>
2) Tomorow, calculate tomorow date :
<?php
$tomorow = date('Y-m-d',mktime(0, 0, 0, date("m") , date("d")+1, date("Y")));
$result = mysqli_query($connect, 'SELECT * FROM events WHERE start_date = "'.$tomorow.'"');
?>
3) 7 days later, calculate 7 days later date :
<?php
$day7 = date('Y-m-d',mktime(0, 0, 0, date("m") , date("d")+7, date("Y")));
$result = mysqli_query($connect, 'SELECT * FROM events WHERE start_date = "'.$day7.'"');
?>
3) Week end, calculte when week end comes :
For this one, I cannot write it so quickly, sorry.
Explanations :
date('Y-m-d',mktime()); gives 2014-09-04 in $today.
Because mktime() is empty, so mktime() is based on the server time, no argument.
Y => year like ####
m => month like ##
d => day like ##
date('Y-m-d',mktime(0, 0, 0, date("m") , date("d")+1, date("Y"))); gives 2014-09-05
This time we gave arguments to mktime(), 0 hour, 0 minutes, 0 second, 09, 04+1, 2014.
date("m") = 09
date("d")+1 = 04+1 = 05
date("Y") = 2014
I hope this might help you.
I'm sorry, but I don't know how put PHP in Wordpress.
Nils.
For the weekend and next 7 days you may have to mix sql and php
Today
SELECT * from tablename where start_date=CURDATE();
Tomorrow
SELECT * from tablename where start_date = CURDATE()+INTERVAL 1 DAY;
For Weekend you have to find the weekend dates first.
using
SELECT DAYOFWEEK
you can find current day . So if you have an array , match with it and
add how many days to reach Saturday and sunday.
I dont know any other easy way
For next 7 days
SELECT * from tablename where start_date >= CURDATE() and
start_date=< CURDATE()+INTERVAL 7 DAY;
Use the tutorial and try yourself :-)
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_curdate
Related
In my dates database I have a table of dates that have two followups to be completed, one after 30 days, one after 60 days. I need to build a page that uses the MySQL query to pull all dates from the dates table that have a 30day value of No (which I can do). Now the tricky part is, I need it to only output the dates that meet that criteria, and are 30 days from the current date.
For example: August 4 & 6 have a 30day value of No, August 5 has a 30day value of Yes. Today's date is September 4. 30-days prior would be August 5.
I need the query to only display August 4 in this case, since it hasn't been 30 days since August 6 and August 5 has already been done.
I am unsure what kind of function to use to do this counting. I appreciate your help
EDIT:
Date - 30day Value
July 1 - Yes
July 5 - No
August 1 - No
August 5 - No
August 6 - Yes
Today's Date is September 2.
The table would display July 5 and August 1, as their 30day values are No, and they are more than 30 days from todays date.
You should use DATEDIFF function:
SELECT ....
FROM your_table
WHERE DATEDIFF(CURDATE(), event_date) = 30
Where event_date is example of your date column.
MySQL's DATEDIFF function allows you to subtract 2 dates in a query.
http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff
DATEDIFF() returns expr1 − expr2 expressed as a value in days from one date to the other. expr1 and expr2 are date or date-and-time expressions. Only the date parts of the values are used in the calculation.
For example:
SELECT some_id, date_column
FROM date_table
WHERE DATEDIFF(CURDATE(), date_column) = 30
You could also select both 30 and 60 days like this and also have a cutoff date of 60 days so it's not searching the whole table:
SELECT some_id, date_column
FROM date_table
WHERE date_column>=DATE_SUB(CURDATE(), INTERVAL 60 DAY)
AND DATEDIFF(CURDATE(), date_column) IN (30, 60)
And since I'm making some assumptions with my understanding of what you're asking, you may also want to do this which will return the results as 'Yes' or 'No' in your result set:
SELECT some_id, date_column,
CASE DATEDIFF(CURDATE(), date_column)
WHEN 60 THEN 'Yes'
WHEN 30 THEN 'Yes'
ELSE 'No'
END CASE AS is_3060_day
FROM date_table
WHERE date_column>=DATE_SUB(CURDATE(), INTERVAL 60 DAY)
Alternatively if you want to accomplish this on the PHP side, you could use PHP's date_diff function:
http://php.net/manual/en/function.date-diff.php
function dateDifference($date_1 , $date_2 , $differenceFormat = '%a' )
{
$datetime1 = date_create($date_1);
$datetime2 = date_create($date_2);
$interval = date_diff($datetime1, $datetime2);
return $interval->format($differenceFormat);
}
$result = dateDifference($date1, $date2)
if ($result==30 || $result==60) {
// Do something
}
you can fetch both the dates and use the php function
$prevdate = date_create("2013-03-15");
$currdate = date_create("2013-12-12");
$diff = date_diff($prevdate,$currdate);
echo $diff->format("%R%a days");
Output
272 days
my graph is not reading between the correct dates that the data was inserted and instead its reading the amount of rows and displaying all the 29 days. Here is the code:
$graphTimeOne = time();
for($graphTimeOne = 29; $graphTimeOne >= 0; $graphTimeOne--){
$sel_timestamp = mktime(0, 0, 0, date("n"), date("j") - $graphTimeOne, date("Y"));
$graphResult = mysql_query("SELECT COUNT(id) FROM user WHERE timestamp >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 29 DAY))");
Basically its suppose to display how many are per day, but instead it displays the total on every day, the interval is 29 days. Any ideas how I can fix it?
Your SQL is incomplete - it is missing the day grouping:
SELECT COUNT(id)
FROM user
WHERE timestamp >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 29 DAY))
GROUP BY DAY(FROM_UNIXTIME(`timestamp`))
Table structure is,
Table name: btq_user
name, email, kall, state_id, datain
Now i want to count number records which has kall = 1 or state_id in( 51, 20, 46) by weekly.
i need the results only by weekly (Mon - Sun) no matter if year changes. lets say for example 31-12-2012 is Monday and 6-1-2013 is Sunday so result should include that as a week. no matter if year changes it should count only with weeks.
This is what i tried but not working.
SELECT
count( if( A.state_id = 51 or A.state_id = 20 or A.state_id = 46, A.state_id,
null ) ) AS state_total, count( if( A.kall =1, A.kall, null ) ) AS appointment,
CONCAT( WEEK( A.datain) , " -
", YEAR( A.datain ) ) AS week
FROM btq_user A
GROUP BY week
ORDER BY A.datain ASC
also is there any possibility to display weeks ( 31-12-2012 - 6-1-2013 ) with results ?
Thank you for reading my question.
Two steps to this:
One, you need a week-truncate operation -- that will take your DATETIME item and give back midnight on the preceding Sunday (if your business rule says that the week begins on Sunday).
That becomes a suitable GROUP BY item. The WEEK() / YEAR() hack isn't suitable for this. It really makes a mess in the last/first week of each year.
In my experience, this exxpression will do the week-truncate trick for you, Sunday - Saturday,
FROM_DAYS(TO_DAYS(TIMESTAMP) -MOD(TO_DAYS(TIMESTAMP) -1, 7))
To get Monday - Sunday weeks, use this expression.
FROM_DAYS(TO_DAYS(TIMESTAMP) -MOD(TO_DAYS(TIMESTAMP) -2, 7))
So you can do this.
SELECT COUNT(whatever), SUM(whatelse),
FROM_DAYS(TO_DAYS(event_time) -MOD(TO_DAYS(event_time) -1, 7)) as WEEKSTART,
FROM TABLE
GROUP BY FROM_DAYS(TO_DAYS(event_time) -MOD(TO_DAYS(event_time) -1, 7))
How to group by week in MySQL?
Second, you need to add six days to that truncated date, so you can display the last day of each week along with the first day.
This is a good way to do that, with a nested query
SELECT whats, elses, weekstart, weekstart + INTERVAL 6 DAY AS weekend
FROM (
SELECT COUNT(whatever) AS whats, SUM(whatelse) AS elses,
FROM_DAYS(TO_DAYS(event_time) -MOD(TO_DAYS(event_time) -1, 7)) AS weekstart,
FROM TABLE
GROUP BY FROM_DAYS(TO_DAYS(event_time) -MOD(TO_DAYS(event_time) -1, 7))
) AS summary
ORDER BY weekstart
Doing lots of this? I suggest you create a stored TRUNC_WEEK function.
I have a table with the following fields:
id - int
name - int
the_date - int
the_date is a unix timestamp for when the row was added
Now I am trying to write a query that will select all rows on the day that is 7 days from now. I'm not talking about select the rows >= 7 days from time(), I need to grab the current day using time(), and then run a SELECT that grabs all the rows that were inserted on the day that is 7 days from the time().
I know how to do it so its within 7 days from the time() with a simple >= SELECT, but I don't know how to do it so it selects all rows whose unix timestamp is on that particular day (7 days from now).
Any help would be greatly appreciated.
The points of intrest here,
i use curdate() to get the current DATE, not DATETIME.
i add 7 days and convert to unix time, which yields the starting second of that day
i do the same for the next day
i structure the where clause to be >= or equal to the target day, but < the start of the next day. This gives a range of seconds that fully covers the target day.
i dont use any functions on the column itself. This is important because if i did, mysql wouldn't be abl;e to use any indexes that exist on the column to fullfill the query.
where the_date >= unix_timestamp(curdate() + interval 7 day)
and the_date < unix_timestamp(curdate() + interval 8 day)
SELECT * FROM `dbname1`.`test`
WHERE
date(FROM_UNIXTIME(`the_date`)) = ADDDATE(DATE(NOW()), INTERVAL 7 DAY);
$todayParts = getdate();
$startToday = mktime(0, 0, 0, $todayParts['mon'], $todayParts['mday'], $todayParts['year']);
$sevebDaysFromNow = 60 * 60 * 24 * 7;
$seventhStart = $startToday + $sevebDaysFromNow;
$seventhEnd = $seventhStart + 60 * 60 * 24;
$sql = "SELECT * FROM <table> WHERE the_date BETWEEN $seventhStart AND $seventEnd";
This will calculate 7 days from the start of the day you are now. Hope this helps
I have a small requirement in my project:
I want to fetch all the records of the previous month from the database.
The structure of the table is as follows:
id clientid task date
1 1 1 01.Feb.2011 12:13
2 1 1 05.Feb.2011 15:22
3 1 0 09.Feb.2011 14:17
4 2 1 11.Feb.2011 19:53
5 1 0 19.Feb.2011 14:27
6 2 1 23.Feb.2011 09:53
7 1 0 01.Mar.2011 14:17
8 2 1 01.Mar.2011 19:53
9 1 0 03.Mar.2011 14:67
10 2 1 03.Mar.2011 09:53
.....................
Here I want to fetch all the records of the previous month of a particular client in Zend Framework.
For Example : If I want client 1 records then It should show me records : 1,2,3 and 5.
Please Suggest some code, or link that helps me......
Thanks in advance
Assuming the date column is a DateTime column, I'd try with something like
$select->from('tablename')
->where('MONTH(date) = ?', date('n', strtotime('last month')))
->where('YEAR(date) = ?', date('Y'))
->where('clientid = ?', $clientId)
;
Note: untested and likely needs tweaking but it's the general direction
This would fetch all rows from tablename where the month is the last month and year is the current year and your clientId is the selected clientId. So the query should become something like
SELECT * from tablename
WHERE MONTH(date) = 2
AND YEAR(date) = 2011
AND clientid = 1;
You could also put the calculation for last month and current year directly into the query, e.g. using the appropriate MySql functions for this instead of calculating them with PHP. This might be more reliable.
You can get the first day of the current month using PHP:
$this_month = mktime(0, 0, 0, date("m"), 1, date("Y"));
$previous_month = mktime(0, 0, 0, date("m")-1, 1, date("Y"));
Then you simply pass this date as a parameter of your query:
SELECT * FROM mytable WHERE date >= ? AND date < ? and client_id = 1
where you replace the ? respectively by '$previous_month' and '$this_month'
If your date field is of the type Datetime you can use the date specific functions in MySQL to do this. Simply construct your statement with Zend_Db_Expr when using database functions.
My Zend_Db skill is a bit rusty, but I think the following does what you want:
$select->from('tablename')
->where(new Zend_Db_Expr('MONTH(`date`) = MONTH(DATE_SUB(NOW(), INTERVAL 1 MONTH))'))
->where(new Zend_Db_Expr('YEAR(`date`) = IF(MONTH(NOW()) = 1, YEAR(NOW()) - 1, YEAR(NOW()))'))
->where('clientid = ?', $clientId)
you can use SQL DATE_SUB and INTERVAL function like:
select * from table where `date` >= DATE_SUB(NOW(), INTERVAL 1 month)
In ZF1 you can write something like:
$select->from('tablename')
->where( 'date >= DATE_SUB(NOW(), INTERVAL 1 month)');