I've column that contains data like so,
07/2002
05/2005
04/2000
month/year
can I filter out data using query, i.e
SELECT * FROM `table` WHERE `fr` < '07/2002'
it should return 04/2000
is't possible using MySQL or I've to use other language to select and filter out data like PHP?
plan
use str_to_date
to convert the start of month values to dates and compare
query
select *
from `table`
where str_to_date(concat('01/', fr), '%d/%m/%Y')
<
str_to_date('01/07/2002', '%d/%m/%Y')
;
output
+---------+
| fr |
+---------+
| 04/2000 |
+---------+
sqlfiddle
note
while the above is a solution to the question as asked, it is just dealing with the symptoms not the underlying issue.
the real issue is the storage type being used to store date information
consider using actual dates to store this information. this causes the following symptoms :
symptoms
complexity : we have to perform further manipulations to transform into the date type we can use
performance ( see above )
maintenance ( see this question )
we can instead fix this issue where it is caused by changing the storage type to correctly reflect the semantic contents ( its date information and should be able to be compared in this way simply )
fix
alter table `table` add column fr_datetype date not null;
update `table`
set fr_datetype = str_to_date(concat('01/', fr), '%d/%m/%Y')
;
-- test conversion to date type
select
'error converting' as test_conversion
from `table`
where concat(lpad(extract(month from fr_datetype), 2, '0'), '/', extract(year from fr_datetype)) <> fr
;
-- only finalise this based on successful completion of above select ( no rows returned )
alter table `table` drop column fr;
alter table `table` change column fr_datetype fr date not null;
simplified solution
select *
from `table`
where fr < '2002-07-01'
;
Use MySQL built in date format, so you can perform queries like this:
WHERE DATE_FORMAT(date_field, '%m') < 7
AND DATE_FORMAT(date_field, '%y') < 2002
Or a simpler solution is to use timestamps (that stores seconds), and you can do things like:
WHERE timestamp_field < 1027407492
Or if you'd like to use dates as you're using it now (not recommended), store them in two columns. One for month and other one for year, then you can query like this:
WHERE month_field < 7
AND WHERE year_field < 2002
I recommend timestamps.
Related
I have a query from table of rows, where is datetime column with only year and month.
The day is always 01 and time is 00:00:00
When selecting data with php query, what is faster?
$date = "2020-04";
$query = "SELECT * FROM table WHERE datum LIKE ?",$date ;
or
$date = "2020-04";
$rok = substr($mesic,0,4);
$mesic = substr($mesic,5,2);
$query = "SELECT * FROM table WHERE YEAR(datum) = ? AND MONTH(datum) = ?",$rok,$mesic;
The table contains 100s thousands of rows
We always used to have the rule:
"Avoid functions in the WHERE Clause".
The background is that the database server has to make a table scan to calculate the function result for each row (even if it is only the key table).
So he cannot use the keys efficiently!
LIKE is faster!
If you use the beginning of the key (as you write), it can also use it efficiently.
I would recommend:
$date = "2020-04";
$sql = "SELECT * FROM table WHERE datum = concat(?, '-01')", $date;
The base idea is not not apply functions (either date functions or pattern matching) on the column being searched, as this prevents the database from taking full advantage of an index on that column (and it involves unnecessary additional computation for each and every row). Instead, you can easily generate the exact value to search for with by concatenating the variable in the query.
In the more typical case where datum had real day and time components, and you want to filter on a given month, you would do:
SELECT *
FROM table
WHERE datum >= concat(?, '-01') AND datum < concat(?, '-01') + interval 1 month
Note that this assumes that you are using MySQL, because the syntax suggests it. Other database have equivalent ways to build dates from strings.
Neither. In both cases you have a function call on the datum column. With YEAR() and MONTH() it is obvious. With LIKE you are converting to a string. Both impede the optimize and prevent the use of indexes.
The correct structure would be:
where datum >= ? and
datum < ? + interval 1 month -- syntax might vary depending on the database
where ? are parameter place-holders for the beginning of the month. I would suggest that you construct this in the application as a date constant or a string constant of the canonical form YYYY-MM-DD.
I have a database table that contains information and has columns 'Date Start' and 'Date End'
I'm wondering if there is a way to show data from the database between those dates.
So for example let's say i schedule something on the 1st december and then it ends on the 3rd. This is my current query
<?
$query2 = mysql_query ( "SELECT * FROM `Announcements` " );
$announecment = mysql_fetch_object ( $query2 ) ;
<div class="page-bg" style="background-image: url('<?echo $announecment->backgroundim;?>');"></div>
<?}?>
Since you did not provide the names for the columns, I'm going to use date_start and date_end to represent them, but you need to use the actual column names.
The query you are looking for is something like this:
SELECT * FROM `Announcements` WHERE `date_start` < NOW() AND `date_end` > NOW();
This is under the assumption that those timestamps are set by the database. If they are set within the application logic and the timezones do not match, this may still give you issues. In that case, instead of using NOW(), you will want to use the php date function to generate a date, and pass that in in place of using the MySQL NOW() construct.
You also will want to use prepared statements, as mentioned in the comments on your original question to avoid SQL injection vulnerabilities.
I have a table in my database that stores user input as a start date and end date after that, my users will have to select a time range and I have to display those records in the table that are within this time range?
Tried stritotime(); and many other unctions but somehow I can't get the right results..
Any possible solution would be appreciated.
Thank you!
May be with:
SELECT count(*) FROM `table`
where
created_at>='2011-03-17 06:42:10' and created_at<='2011-03-17 06:42:50';
or use between:
SELECT count(*) FROM `table`
where
created_at between '2011-03-17 06:42:10' and '2011-03-17 06:42:50';
it depends on your record what u want to display because i didnt see your table and an exemple what you you really to do so just change count(*) and get whatrecords you want.
EDIT:
if the users will select a range of time then they will be variables
then it will be something like that
SELECT records FROM `table`
where
created_at >= '".$var_start_time."' and ended_at <= '".$var_end_time."';
you can use in mysql query BETWEEN ... AND ... comparasion operator
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between
You can simply do this in your SQL, which is the recommended approach. If you have these start and end times stored in your database table as native DateTime types, for example, you can use your DBMS' Date functions to select the range as a UNIX timestamp (if that's what what you want).
SELECT UNIX_TIMESTAMP(`start_time`), UNIX_TIMESTAMP(`end_time`) FROM `table` WHERE `start_time` > INTERVAL -1 DAY AND `end_time` < NOW();
That's one example (assuming you're using MySQL) where you select all rows in the table where the column start_time is within the past 24 hours and the end_time column is up to the current server time.
To get the formatted date and then do the conversion to a UNIX time-stamp in PHP use:
SELECT `start_time`, `end_time` FROM `table` WHERE `start_time` > INTERVAL -1 DAY AND `end_time` < NOW();
and then in PHP you can do:
$result['start_time'] = strtotime($result['start_time']);
$result['end_time'] = strtotime($result['end_time']);
Keep in mind that strtotime expects the formatted date to comply with PHP's date parsing rules found here.
P.S: The function in PHP you're looking for is strtotime not stritotime.
So basically I have a table -
ID | from | To
-----------------
1 | 25.05.2012|30.05.2012
-----------------
2 | 15.05.2012|20.05.2012
-----------------
3 | 25.06.2012|30.06.2012
and I have a query
SELECT date.*
FROM table AS date
WHERE (date.from >= '25.05.2012' OR date.to >= '25.06.2012' ) AND (date.to <= '30.05.2012' OR date.from <= '25.05.2012' )
GROUP by date.id
but it's not working, what could be the problem?
date is a reserved keyword in MySQL, try calling the table something else!
You are performing string comparisons, not date comparisons, eg: 26.05 is greater than 25.06 since the comparison only reaches as far as the second character of the string and determines that 6 is greater than 5.
In order to perform date comparisons you either need to store the value as a date (preferable) or in an appropriate string form eg yyyyMMdd.
SELECT * FROM table WHERE (from >= '25.05.2012' AND to <= '25.05.2012') GROUP by id;
"date" is a reserved string in MySQL. I'd recommend renaming all tables and columns with that name to a custom one. This might already solve your problem.
Point 1 : table, date, from are reserved keywords. Those should not be used for naming tables. If your table name is table, use backticks
Point 2 : When you have one table why you are creating alias for that?
Point 3 : While comparing date should be in format of yyyy-mm-dd. I believe from and to columns are timestamp.
Point 4 : No need of GROUP BY statement at the moment as you are not using any aggregate function such as SUM, COUNT, etc
Your query should be
SELECT *
FROM `table`
WHERE
(`from`>= '2012-05-25' OR `to`>= '2012-06-25' )
AND
(`to` <= '2012-05-30' OR `from` <= '2012-05-25');
If you want to pass date as 25.05.2012 , use STR_TO_DATE function to convert string to date.
I want to SELECT all the rows from the table that correspond to a specific date.
I have the timestamp stored in the pattern 2010-08-18 04:43:00.
How can I query the table if I want to select all the rows that fall within a day's time?
One way I can think of is get the day's timestamp, convert it into Unix timestamp and then query the table. But that sounds like a lot of work. Is there any easier alternative?
Thanks a lot in advance.
SELECT *
FROM `table_name`
WHERE `date_column` LIKE '2010-08-17 %';
Or:
SELECT *
FROM `table_name`
WHERE DAY( `date_column` ) = 17
AND MONTH( `date_column` ) = 08
AND YEAR( `date_column` ) = 2010
LIMIT 0 , 30
Reference: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
The approach outlined by Michael works, but is string-based and as such not as efficient as an integer-based search.
I don't really see a problem in creating two UNIX timestamps, one for 00:00:00 and one for 23:59:59, and checking to see if you fall within that time. (Be sure to actually calculate these two separate values to make sure you account for daylight savings time).
You can even use MySQL to get those values if you really don't want to do it yourself (SELECT UNIX_TIMESTAMP("$Timestamp 00:00:00"), UNIX_TIMESTAMP("$Timestamp 23:59:59")), and then use those two values.
If you have a small dataset, Michael's approach above is fine.
Quite simply:
SELECT *
FROM `table_name`
WHERE DATE(`date_column`) = '2010-08-17';
Note that it will only be efficient if your date_column is of type TIMESTAMP or DATETIME.
Edit:
Since Martin raised a point related to performance, you might want to try this instead if speed is an issue (on a huge data set). BETWEEN will make use of any available indexes.
SELECT *
FROM `table_name`
WHERE `date_column` BETWEEN '2010-08-17 00:00:00' AND '2010-08-17 23:59:59';