I have a DATETIME field. I would like to select all the records that have been updated in the last week. Right now I'm using this query:
SELECT SUM(mins_spent) as time_sum FROM todos WHERE
lastUpdate >= '2008-12-22' AND lastUpdate <='2008-12-28'
But the results i get seem to be different depending on time of the day, e.g on 7 PM I might get 17 hours and on 11 PM I'l get 14 hours even though it should be increasing, not decreasing. I was thinking of changing the query to:
SELECT SUM(mins_spent) as time_sum FROM todos WHERE
lastUpdate >= '2008-12-22 00:00:00' AND lastUpdate <='2008-12-28 00:00:00'
Would it help at all? Suggestions please..
'2008-12-22' should equal '2008-12-22 00:00:00'.
Are you wanting "till end-of-day 28th?" If so, add 23:59:59 to the 2nd date.
Alternatively, you can use lastUpdate < "2008-12-29".
How are you tracking changes to an existing ToDo? INSERT and/or DELETE? Or UPDATE?
If you're DELETE'ing records upon "completion," you'll just have fewer records.
If you're UPDATE'ing, are you allowing dates to change to beyond the current week? If so, they'll be removed from your results.
To see what's happening, You may try grabbing a few aggregates on the table, mins_spent, and lastUpdate (mark down the values and run occasionally to see how they change).
SELECT count(*) AS Total
FROM todos
WHERE lastUpdate >= '2008-12-22' AND lastUpdate <= '2008-12-28 23:59:59'
SELECT min(mins_spent) AS Min, max(mins_spent) AS Max, avg(mins_spent) AS Avg
FROM todos
WHERE lastUpdate >= '2008-12-22' AND lastUpdate <= '2008-12-28 23:59:59'
SELECT min(lastUpdate) AS Min, max(lastUpdate) AS Max
FROM todos
WHERE lastUpdate >= '2008-12-22' AND lastUpdate <= '2008-12-28 23:59:59'
Judging from the MySQL 6.0 Reference Manual for Date and Time Types, you should be more or less OK as written. However, if it really isn't working, then you may have found a reportable bug.
A DATE value is coerced to the DATETIME type by adding the time portion as '00:00:00'. To perform the comparison by ignoring the time part of the DATETIME value instead, use the CAST() function to perform the comparison in the following way:
date_col = CAST(NOW() as DATE);
Your queries say '<= '2008-12-28'; that should be strictly less-than, not less-than-or-equal.
One very fine point would be: do the expressions you wrote get treated as DATETIME (because the LHS is a DATETIME column) or as a DATE (because the RHS is best treated as a DATE) or, indeed, does the DATETIME get converted to a string to match the RHS? It would make a difference if the LHS is converted to a DATE, because any time on the 28th would come in range, whereas you seem to want everything from the 21st to the 27th. What happens if you do explicitly fixup the types with casts?
Also, is the MySQL server running in the same time zone as you? There seemed to be an 'off-by-an-hour' difference between what you were seeing and the nominal end of day? I'm still not sure exactly how that might be (mis-)working, but it could be an otherwise unaccounted for factor.
Related
how to search between two date , when date format in database like :
2015-10-10 02:23:41 am
i just want to search between two date with format :
2015-10-10
without
02:23:41 am
any ideas please ?
Your question isn't completely clear. But, I guess you hope to find all the rows in your table where Date occurs on or after midnight on 2015-08-05 and before midnight on 2015-09-11 (the day after the end of the range you gave in your question.
Those two search criteria will find all the rows with Date values in the range you specified. (I'm ignoring the 02 at the end of 2015-09-10 02 in your question because I can't guess what it means, if anything.)
Try this query:
SELECT *
FROM table
WHERE `Date` >= '2015-08-05'
AND `Date` < '2015-09-10' + INTERVAL 1 DAY
This has the benefit that it can exploit an index on the Date column if you have one, so it can be fast.
You could write
SELECT *
FROM table /* slow! */
WHERE DATE(`Date`) BETWEEN '2015-08-05' AND '2015-09-10'
That's slightly easier to read, but the WHERE condition isn't sargable, so the query will be slower.
Notice that the beginning of the range uses >= -- on or after midnight, and the end of the range uses < -- before midnight.
Pro tip: Avoid the use of reserved words like DATE for column names. If you make mistakes writing your queries, their presence can really confuse MySQL, not to mention you, and slow you down.
May I suggest:
select * from table where cast(date as date) between '2015-08-05' and '2015-09-10'
When your where clause is based on a timestamp, but you're using date as the parameters for your between, it excludes anything that happens on the second date unless it happened precisely at midnight.
When using the end date for the range, include the time of the end of the day:
SELECT *
FROM YourTable
WHERE date BETWEEN '2015-08-05' AND '2015-09-10 23:59:59'
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).
I'm trying to do a SELECT * FROM but only items that are less than 30 days old. Here is my select code:
SELECT * FROM `{$table_name33}` WHERE `type`='wpst-requiredinfo' ORDER BY `foreignkey` ASC;
However, my problem is that I can't figure out how to add WHERE AND last_updated is less than 30 days.
I'm not exactly sure how to write the query, but the date is showing up like this: 1428412603 in the table column, it doesn't look much like a date to me. I don't know where to start.
Try this where clause:
WHERE `type`='wpst-requiredinfo' and
last_updated >= date_sub(now(), interval 30 day)
EDIT:
Your date seems to be in Unix time format.
WHERE `type`='wpst-requiredinfo' and
last_updated >= unixtime_timestamp() - 30*24*60*60
Note: this puts all the functions on the current time. In particular, it does not use FROM_UNIXTIME(last_updated). This ensures that an index can be used for this part of the query. The best index would be on (type, last_updated).
Here is my table
I am executing a query that give me result of fields whose item_valid_from must be greater than today's date and item_valid_to must be less than today.
My query is
select *
from tbl1
where item_valid_from >= CurDate()
and item_valid_to < CurDate()
Any Solution?
I would advise you to change item_valid_* field formats to DATE field format. You will save you a lot of trouble in the future.
But ok, if you don't want to do that, then you can use STR_TO_DATE() function:
SELECT *
FROM `table`
WHERE CURDATE() BETWEEN STR_TO_DATE(`from_field`, '%d-%m-%Y') AND STR_TO_DATE(`to_field`, '%d-%m-%Y')
demo
Assuming the datatype item_valid_from and item_valid_to is DATE, TIMESTAMP, etc, then you have your operators backwards. Think of the time as seconds since 1970, since this is how it is stored in unix time. That means that item_valid_from is going to be smaller than item_valid_to, and you want it to display when today is somewhere between them. You want the item_valid_from to be less than or equal to now, and the item_valid_to to be greater than now (not in the past).
SELECT *
FROM tbl1
WHERE item_valid_from <= CURDATE() AND item_valid_to > CURDATE()
See this SQL Fiddle for an example, only 2-4 are valid and show up in the results being valid from a date in the past and expiring on a date in the future.
You have to use following query which change current date format then compare date and fetch result :
SELECT *
FROM tbl1
WHERE date_format(item_valid_from,'%d-%m-%Y') >= date_format(CurDate( ),'%d-%m-%Y')
AND date_format(item_valid_to,'%d-%m-%Y') < date_format(CurDate( ),'%d-%m-%Y')
Please Check this :http://sqlfiddle.com/#!2/561d0/2
I am currently storing dates as Unix Time Stamps in an INT(10) column in a mysql version 4.0.8 db (MyISAM engine).
I query these dates to extract records between a date range using the following SQL:
$sql = "SELECT `users`.`real_name`, `users`.`user_value`, `clients`.`client_name`, `clients`.`client_stars`, `timing`.`start_date`, `timing`.`end_date`, `projects`.`project_name`
from timing
LEFT JOIN users on (users.id = timing.user_id)
LEFT JOIN clients on (clients.id = timing.client_id)
LEFT JOIN projects on (projects.project_id = timing.project_id)
WHERE start_date BETWEEN :start_date AND :end_date";
I am using PDO, hence the params.
I am 100% sure the :start_date and :end_date vars are correct in all cases as I have checked these. Also start_date is not ambiguous and there are no warnings/notices regarding this query.
My problem is that I do not get the rows expected. If I ask for rows between Midnight 2013/11/14 and Midnight 2013/11/15, the expectation is ONLY results from the 14th. However, rows from the 15th are also passed - but not all of them.
I also just tested between 1384473600 and 1384473600 - which is between midnight today and midnight today (as in the same timestamp).
The rows returned should be 0, yet it has returned all rows from today (for instance the first row returned has a start_date value of 1384524193)!
Have I missed something about how the between operator works in mySQL? How can it return rows when the min and max are the same?
I have tested and tested, and nearly every time I make a query, rows are returned that are ABOVE the specified between ceiling.
What is going wrong?
BETWEEN is a notoriously bad way to match dates and timestamps, because it's inclusive of both ends of the range.
This may work better for you
WHERE start_date >= :start_date
AND start_date < :end_date + 86400
The magic number 86400 is the number of seconds in a day. This selects all start_date values between midnight on the :start_date parameter inclusive, and then excludes all values on or after midnight on the day after the :end date. If you were using actual timestamps, you could say + INTERVAL 1 DAY instead of + 86400.
Although I do not know why, when I reversed the logic it worked perfectly.
WHERE timing.start_date < :end_date
AND timing.start_date >= :start_date
This did not work however, and returned the same erroneous results.
WHERE start_date >= :start_date
AND start_date < :end_date
Can Anyone explain why?