MySQL query where date range is exactly 1 month - php

I am trying to abstract querying a month of data on the MySQL level without having to implement a series of conditions that determine the last day of a given month on a given year. LAST_DAY() seemed to be the answer but it appears to only return the date and not the provided time.
SELECT LAST_DAY('2011-02-05 23:59:59');
returns
2011-02-28
When I try to use it in a query, I lose all the entries from the last day of the month because without time the date value is not accepted.
SELECT * FROM subscriptions
WHERE (`modified_at` BETWEEN '2014-12-01 00:00:01' AND LAST_DAY('2014-12-01 23:59:59'));
How can I modify this query so that the LAST_DAY function either generates the last time of the day or preserves the time given?

How about changing the logic to ignore times?
SELECT *
FROM subscriptions
WHERE `modified_at` >= '2014-12-01' AND
`modified_at` < date_add('2014-12-01', interval 1 month)
And this doesn't need last_day().

Use ADDTIME(expr1,expr2);
Like this:
ADDTIME(LAST_DAY('2011-02-05 23:59:59'), '23:59:59')

Related

Request to find out the date in 2 days

How to write a sql query to find out that there are 2 days left before the current date.
In php, this can be done via:
$res['end_date'] - time () < 86400 * 3;
How can I do the same after 1 sql query, well or better, only 2 days, if less so that it does not work out, well, if it works out, it's okay.
UPD:
It is necessary to compose a sql query that will select only those records that have 2 days left before the end_date expires
The type is int for the field end_date and is stored via the time () function in php.
Can't compose a WHERE clause.
You can use the FROM_UNIXTIME function to convert it to a DateTime you can then use the NOW() plus 2 days to check if the date is under 2 days. You then have to check that the date is before the current time otherwise you'll get dates that have already gone.
SELECT
end_date
FROM
table
WHERE
FROM_UNIXTIME(end_date) <= NOW() + INTERVAL 2 DAY
AND
FROM_UNIXTIME(end_date) > NOW()
Assuming that you are storing an epoch timestamp (the number of seconds since January 1st, 1970), I would recommend:
select *
from mytable
where end_date >= unix_timestamp() and end_date < unix_timestamp() + 2 * 24 * 60 * 60
unix_timestamp() gives you the current epoch. You can use simple math to add two days to that.
The upside of this approach is that this does direct filtering against the store value, so this can take advantagae of an index on end_date - as opposed to converting the timestamp to a date, which requires converting the whole column before the filtering can happen. So this is much more efficient.
You can ajust the inequalities as you prefer. I used a half-open interval (inclusive on the lower bound and exclusive on the upper bound), which is a widely used approach.
I ended up doing this:
$time = time();
$params = $db->query("SELECT * FROM `params` WHERE (`end_date` - {$time}) < 86400 * 3");
And it worked.
I always do
select *
from mytable
where FROM_UNIXTIME(end_date) < NOW() + INTERVAL 2 DAY
This will get results where two days in the future is ahead of the end date ie, anything that will end within 2 days (or has already ended as I didn't add a check for that)
Edit: I see you can't use where
If you cannot use where clause
select FROM_UNIXTIME(end_date) - INTERVAL 2 DAY as end_date
from mytable
And then check in php if the result is before or after. This will show all results however

Get all results from that day of Datetime

I would like to be able to get all the results from a MySql database that have the same day as a certain DateTime.
For example if the DateTime's date is "2/5/2018 10:15pm" all MySql results who's DateTime day is the 5th and in the same month and year (Ignoring the time) are returned.
I tried using
SELECT * FROM posts WHERE timestamp=:timestamp, Array(':timestamp' => $targetTime)
But that only gives results with the exact same DateTime without ignoring the time.
Use >= and < so it will preserve the index if you have.
WHERE timestamp >= DATE(:timestamp)
AND timestamp < DATE(:timestamp) + INTERVAL 1 DAY
DATE() will strip the time.
Here's a Demo.
Could you try ?
SELECT * FROM posts WHERE DATE(timestamp) = DATE($targetTime);

Compare date and datetime

I want to compare a datetime from sql and the todays date.
The datetime in sql is for example 2015/05/09 12:00:00 and the current date is 2015/05/09. I want to compare these things if they are equal, but for the whole day so the time is a problem. I have the following query.
$q1="SELECT reservations.reservation_id, reservations.room_id, room.room_rate, reservations.arrival_date, reservations.departure_date,
meals.meal_rate, room.room_rate, roomtype.max_persons,
CONCAT(clients.first_name,' ',clients.last_name)as name
FROM reservations, clients, meals, room, roomtype
WHERE reservations.room_id=room.room_id AND reservations.client_id=clients.client_id AND room.roomtype_id=roomtype.roomtype_id
AND reservations.meals=meals.meal_id AND reservations.arrival_date=CURDATE()
GROUP BY reservation_id
";
reservations.arrival_date=CURDATE() this is equal only at 12:00:00 o'clock. i want that to be equal for the whole day.Actually i want to compare if these two dates are equal without time but my database must be datetime with the time...
does anyone has an idea?
thanx in advance
You should learn to use standard join syntax. Simple rule: Never use commas in the from clause.
The answer to your question is either the date() function (or something similar):
where date(reservations.arrival_date) = CURDATE()
Or an inequality:
where (reservations.arrival_date >= CURDATE() and
reservations.arrival_date < date_add(CURDATE(), interval 1 day)
)
The second is actually preferred because it can make use of an index on reservations(arrival_date).

How to use only one query to get the data every day within one year?

I want to get the data every day within one year backward but I have to use 365 queries for each day like:
for ($i = 0; $i<365; $i++){
$end_day = ...; // the end time of each day
$start_day = ...; // the start time of each day
$query = select count(*)....where created < $end_day AND created > $start_day
}
I think that my current solution makes the system very slow. Is there any way to just use one query only?
Assuming that your created column is a DATETIME or TIMESTAMP, and the data stored is more granular than a day:
SELECT COUNT(*) ... GROUP BY YEAR(created), MONTH(created), DAY(created)
COUNT is an aggregate function and will apply to each group, i.e. you will have one row per group and that row will have the number of records in that group. As we've made a group a day, this is the data you want.
You cannot just group by DAY(created) as DAY returns the day of the month, so we also need to put month and year in to make sure days are discrete.
You probably want to have a WHERE created > $start AND created < $finish to limit it to some time frame (or a WHERE YEAR(created) == 2010).
References:
MySQL Query GROUP BY day / month / year
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
You can use a group by clause. http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
if you have time in your date you'll have to format it to get only the date (http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-format)
select count(*), created from my_table group by created
If it's a datetime column already:
SELECT COUNT(*),DATE(created) as d ..... GROUP BY d;
If it's stored as a unix timestamp:
SELECT COUNT(*),DATE(FROM_UNIXTIME(created)) as d ..... GROUP BY d;
Basically, you can use the Mysql Date and Time functions to format the column such that you get just a date out of it, and then group by those dates to get a count for each date.

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