SQL Date Range - Select all if no start point supplied? - mysql

I am having hard time figuring out how I can select records if my (Between From AND To) is missing From.
Eg. On the form I have date range, and if user enters only TO and leaves FROM blank how can I select ALL records up to that point.
My issue occures here,
SELECT * FROM table WHERE date BETWEEN from AND to;
This is my query and I would like to use this same query and just modify my variables so that I don't have to have multiple SELECTS depending on what data was entered.
Thanks

I would suggest that you arrange your application to have two queries:
SELECT *
FROM table
WHERE date BETWEEN $from AND $to
and:
SELECT *
FROM table
WHERE date <= $to
Then choose the query based on whether or not $from is suppled.
Why? Both queries can take advantage of an index on date. In general, MySQL does a poor job of recognizing index usage with an or condition.
Alternatively, you can use AlexK's suggest and set $from to some ridiculously old date and use the query in the OP.

Try something like:
SELECT *
FROM table
WHERE ($from = '' AND date <= $to) OR
(date BETWEEN $from AND $to);

You can either do this with Giorgos' selection above, or using a union:
SELECT *
FROM table
WHERE date BETWEEN $from AND $to
UNION
SELECT *
FROM table
WHERE date <= $to AND $from IS NULL
Personally I think Giorgos' solution is a bit cleaner, but there are times you'll want a UNION so I'm including for completeness sake.

Related

Mysql subquery or something better

I am somewhat new to mysql and I am having an issue on how I should best write the following query. Say I have a table that has a datetime column as well as a few others I want to search on. Since this is just one table, I don't think a join statement would be appropriate here (but I may be wrong since I have not done much in the way of join statements) and I think a subquery is what I need here. So my initial query is to search the table based on a search string the user entered and then I want to limit that on a datetime (start date and end date) also specified by the user in an HTML form.
Table Schema
id, datetime, host, level, message
I want to select any rows that contain $searchstring first so something like ...
SELECT * FROM $table WHERE (level LIKE '%$searchstring%') OR (message LIKE '%$searchstring%') LIMIT $offset,$limit
If I want to limit the above results also by the datetime column, the query would look something like this ...
SELECT * FROM $table WHERE (datetime >='$startdate') AND (datetime < '$enddate')
How can I best merge these queries into one so I can first get any rows that match the search query and then further limit the rows by the start and end datetime?
TIA
You can achieve that by using a single where condition.
In your case:
SELECT * FROM $table WHERE ((level LIKE '%$searchstring%') OR (message LIKE '%$searchstring%')) AND (datetime >='$startdate') AND (datetime < '$enddate') LIMIT $offset,$limit
You don't have to use a JOIN but only add a condition
SELECT *
FROM $table
WHERE (level LIKE '%$searchstring%' OR message LIKE '%$searchstring%')
AND
datetime >='$startdate'
AND datetime < '$enddate'
LIMIT $offset,$limit

SQL select order by date in varchar

I have my date in database in varchar column and i can't change it. However i want to sort things from newest to latest. My date in database looks like:
2014-09-22 10:28:28
So what i try is something like:
$sql = "SELECT * FROM axnmrs_cases WHERE vin = :vin ORDER BY STR_TO_DATE(date_created,'%b-%e-%Y') ASC LIMIT 30";
But unfortunately this not change anything for me , even if i change ASC to DESC , nothing changeing in result
and also something like:
$sql = "SELECT * FROM axnmrs_cases WHERE vin = :vin ORDER BY CONVERT(date_created, date, 103)";
This throw syntax SQL error and I have no idea why.
Is here anybody who can show me the right way?
Date stored in varchar is not a real date and hence the order by also does not give you what you want. The best approach would be store date always in mysql native data types. However in your case you can use str_to_date() function to convert the varchar dates to real date and then use it for sort something as
order by str_to_date(date_created,'%Y-%m-%d %H:%i:%s');
$sql = "SELECT * FROM `axnmrs_cases` WHERE `vin` = ':vin' ORDER BY `date_created` ASC LIMIT 30";
Already tried something like this?
You are using the wrong format in your STR_TO_DATE function, if the date is in the format:
2014-09-22 10:28:28
Then you need to use
STR_TO_DATE(date_created, '%Y-%m-%d %H:%i:%s')
i.e. the format you give should match the format your varchar is in.
Example on SQL Fiddle
In your case you are using '%b-%e-%Y', so you are looking for a date like Jan-1-2014, for a full list of the specifiers in the format defintion see the My SQL Docs for DATE_FORMAT
Also, CONVERT(date_created, date, 103) does not work because it is SQL Server Syntax.
Finally, I would really, really try and change the column data type. Storing dates as a varchar is never a good idea. Anything else is just a workaround, not a solution.

Data Retrieval in MySQL

I want to retrieve some data from a table where the age is in a certain range.
EXAMPLE
Persons with age from 20 to 30 years. How can I do it? I tried with the following query, but I was unable to get it.
$age="SELECT *
From rec_patient_reg
WHERE p_age >='$afrom' <= '$to'";
$result1=mysql_query($age)
or die(mysql_error());
while($result = mysql_fetch_array($result1)) {
echo "<b>Patient ID</b> = " .$result["Patient_id"] . " <br>";
echo "<b>NAME</b> = ".$result["p_fname"]."<br><br>----------------<br><br>";
Please help me.
I bet you are not getting any error message since you are using mysql. Take a look at this example below,
SELECT *
FROM tableName
WHERE Age >= 20 <= 25
This is not allowed on any other RDBMS but MySQL allows it. What it does is it implictly allows boolean expression on the rightmost side of the filter, eg
SELECT *
FROM tableName
WHERE (Age >= 20) <= 25
So in this case, the value is now parsed into (let's say Age = 5)
WHERE 0 >= 25
causing you to retrieve unexpected result.
You can use BETWEEN if you want to search for ranges,
SELECT *
From rec_patient_reg
WHERE p_age BETWEEN '$afrom' AND '$to'
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
First thing, do not use mysql_* functions as they are deprecated.
Your query should be:
SELECT *
FROM `rec_patient_reg`
WHERE `p_age` BETWEEN '$afrom' AND '$to'
Maybe like this?
$age = "SELECT * FROM rec_patient_reg WHERE p_age >='$afrom' AND p_age <= '$to'";

Querying Where date_created without time is same as last_updated without time

In MySQL, I need to write a query (if possible) that finds all rows of a table where the date_created is the same as last_updated. The rub is that I need to ignore the time. Basically, I'm looking for user rows that were created and activated the same day (we don't store an activation date). So presumably the dates would be the same but the times may be different.
You could use the DATE() function, which returns only the date portion of a datetime value. This allows you to compare just the date portion of the values:
SELECT * FROM table_name
WHERE DATE(date_created) = DATE(last_updated)
The timezone may be relevant here. So you may want to cast the datetime values to the user's timezone prior to using the DATE() function, using CONVERT_TZ().
Try this:
SELECT *
FROM table_name
WHERE DATE_FORMAT(date_created, '%Y-%m-%d') = DATE_FORMAT(last_updated, '%Y-%m-%d')
not pretty but works:
SELECT *
FROM table_name
WHERE day(date_created) = day(last_updated) and
month(date_created) = month(last_updated) and
year(date_created) = year(last_updated)

mysql match a year withing datetime field

I am wondering if this is possible, in my database table, I have a datetime field, I wanting to query that table and pull in all the rows that have a posted date of 2011, however my date posted column is dateTime, so the form looks like this,
2011-06-12 00:00:00
How can I query the table to return all 2011 rows?
SELECT * FROM yourtable WHERE YEAR(datetime_column) = '2011'
Read more about YEAR()
It should work with datetime type too.
SELECT * FROM tblName WHERE YEAR(column) = '2011'
Try with:
SELECT *
FROM your_table
WHERE EXTRACT(YEAR FROM datetime_column) = '2011'
You can even sub-string it if you want...
SELECT * FROM tblName WHERE substr(column,1,4) = '2011'
I would however recommend creating a "date dimension" table, and then splitting your dateTime field into separate date and time fields, then joining to the "date dimension" table via the date field, which allows for much better functionality. See the answer I put on the following post for more information about using a "date dimension" table.
Select all months within given date span, including the ones with 0 values
You can join your table to it as follows;
SELECT tblName.*
FROM tblName
INNER JOIN dimDates AS dd
ON tblName.dateField = dd.dd_date
AND dd.dd_date = "2011"