MSQL joins including two different DATE between condition - mysql

I have written the below query.
SELECT bmr_multi_price. *
FROM bmr_multi_price
INNER JOIN bmr_rooms ON bmr_rooms.resort_id = bmr_multi_price.resort_id
AND bmr_rooms.id = bmr_multi_price.room_id
For this above query i have got the below result set.
But I wanted to include the below condition to achieve the above result.
WHERE ( '08/02/2013' BETWEEN bmr_multi_price.from_date AND bmr_multi_price.to_date ) OR ( '08/03/2013' BETWEEN bmr_multi_price.from_date AND bmr_multi_price.to_date )

If the query isn't returning expected results, the likely explanation is that you're comparing strings, and not dates.
The MySQL STR_TO_DATE function is a convenient way to convert strings in a given format into a DATE value. I'm going to guess that string represents a date in mm/dd/yyyy format, based on the values returned in the resultset.
STR_TO_DATE('08/12/2013','%m/%d/%Y')
If those columns are defined as character, rather that DATE, then you can convert them as well:
STR_TO_DATE(bmr_multi_price.from_date,'%m/%d/%y')
MySQL provides a DATE datatype which makes working with dates much easier and (usually) much more efficient.

Related

Mysql optimizing date filter

Is there any difference in any sql engines (and particularly in mysql) in the following two queries?
SELECT * FROM table where date = '2019-01-01'
And:
SELECT * FROM table where date = DATE('2019-01-01')
Doing an explain returns the same result, but perhaps there's some sort of difference that I'm not catching? I need to run a query against a multi-billion row table and am trying to optimize it before running.
There should not be. The expression DATE('2019-01-01') should be evaluated during the compilation phase turning the result into a date. Similarly, the constant value '2019-01-01' is implicitly converted to a date for the comparison.
This allows MySQL (and most other databases) to use indexes and partitions defined on that column.
Date() function Extracts the date part of a date or date/time expression
for example the value of the field name BirthTime is "2017-09-26 16:44:15.581"
so you have to use the following query to check the date :
SELECT DATE(BirthTime)
result is : 2017-09-26

Mysql select where date between 'yy/dd/MM' and 'yy/dd/MM'

I am stuck in a situation where I am reading data from CSV file through 'LOAD DATA LOCAL INFILE' and storing it in Mysql table.
The date column in my table is of type string.
The below query is not working if my Date format is 'yy/dd/MM', it only returns 2 records
select column1, column2 from myTable where date between '16/08/15' and '16/08/20';
and if I ran this:
select column1, column2 from myTable where date > '16/08/15';
It return all records.
Is there a way to ran the first query so I can specify start and end date ?
Turn your dates into 'yyyy-mm-dd' format before using them inside queries, and it will be easier.
Instead of passing the year as yy try to pass it as yyyy in the date string since my sql stores dates in that format.Since every year is a four digit one, giving a two digit year in the where clause in order to pull out all records greater than that year will actually pull out all the records.
Since you say your date column is of type "String" and not DATE so in your query mysql is not operating the between function on dates, instead it's operating it on strings. You probably need to cast you string dates to actual dates before applying the between function. see e.g. str_to_date function.

Mysql query help to display results less than given date

I am having my date field in Mysql which is stored as char is as follows 050712.. Now I would like to display the results which are available in the database which are less than this date. I write as follows
Condition should fail
select * from tblFedACHRDFI where date_format(changedate,'%m/%d/%Y')> 05/08/12;
This is displaying all records which are available but I don't need that I would like to display only when date is 05/06/12 which means
True Condition
select * from tblFedACHRDFI where date_format(changedate,'%m/%d/%Y')> 05/06/12;
The same worked for me in Sqlserver when I write as follows
Records not getting displayed which is true as per my requirement
select * from tblFedACHRDFI where
CONVERT(datetime,(SUBSTRING(ChangeDate,1,2)+'/'
+SUBSTRING(ChangeDate,3,2)+'/'+dbo.Years
(SUBSTRING(ChangeDate,5,2))+SUBSTRING(ChangeDate,5,2)))>
'05/08/2012'
So can any one help me where I went wrong in MySql statement..
A MySQL date should be YYYY-MM-DD, column type should be DATE.
If you wish to store a date any other way (for example, a CHAR(6) as you do here), you'll have to use conversions each time you use the date. This is slower, uses more CPU, and can fail because you can store invalid values in your CHAR field.
It does work, however. Use the STR_TO_DATE function to convert your CHAR column to a proper date. Now you can compare it against a proper date, use INTERVAL functions, the whole shebang:
select *
from tblFedACHRDFI
where str_to_date(changedate,'%m%d%Y') > "2012-08-05";

How can i do the sumation of time in mysql query?

I have a table like this :
And in this table you can see the last column totalloginFinal, I want to do the sum of all time, its will be about 84 hours,
I am trying with addtime and sum function but not getting proper result.
Thanks a lot in Advance.
Try this variant -
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(totalloginFinal))) FROM table_name;
From the reference - The SUM() and AVG() aggregate functions do not work with temporal values. (They convert the values to numbers, which loses the part after the first non-numeric character.) To work around this problem, you can convert to numeric units, perform the aggregate operation, and convert back to a temporal value.
GROUP BY (Aggregate) Functions.
try convert it to second and then sum the seconds and convert it back from second to time
like :
SELECT SEC_TO_TIME(SUM(SECOND(totalloginFinal))) as Total from mytable

Explain how the following query works?

I have a mysql query which works in a strange way. I am posting the 2 queries with input data changed and the output are listed under each query.
Query 1 (Area to be noted BETWEEN '13/05/11' AND '30/05/11'):
SELECT COUNT(pos_transaction_id) AS total,
DATE_FORMAT(pt.timestamp,'%d-%m-%Y %H:%i:%S') AS Date,
SUM(amount) AS amount
FROM pos_transactions pt
WHERE DATE_FORMAT(pt.timestamp,'%e/%m/%y') BETWEEN '13/05/11' AND '30/05/11'
GROUP BY WEEK(pt.timestamp) ORDER BY pt.timestamp
Output:
Query 2 (Area to be noted BETWEEN '3/05/11' AND '30/05/11'):
SELECT COUNT(pos_transaction_id) AS total,
DATE_FORMAT(pt.timestamp,'%d-%m-%Y %H:%i:%S') AS Date,
SUM(amount) AS amount
FROM pos_transactions pt
WHERE DATE_FORMAT(pt.timestamp,'%e/%m/%y') BETWEEN '3/05/11' AND '30/05/11'
GROUP BY WEEK(pt.timestamp) ORDER BY pt.timestamp
Output:
Now when the range is increased in the second query why am I getting just one record ? And even in the first query I am getting records which is out of range. What is wrong with it??
EDIT
The changed query looks like this and still not doing what I wanted it to do.
SELECT COUNT(pos_transaction_id) AS total,
DATE_FORMAT(pt.timestamp,'%d-%m-%Y %H:%i:%S') AS Date,
SUM(amount) AS amount
FROM pos_transactions pt
WHERE DATE_FORMAT(pt.timestamp,'%e/%m/%y') BETWEEN STR_TO_DATE('01/05/11','%e/%m/%y') AND STR_TO_DATE('30/05/11','%e/%m/%y')
GROUP BY WEEK(pt.timestamp) ORDER BY pt.timestamp
The output is:
I think you're seeing the result of the intersection of two bad practices.
First, the date_format() function returns a string. Your WHERE clause does a string comparison. In PostgreSQL
select '26/04/2011' between '13/05/11' AND '30/05/11';
--
T
That's because the string '26' is between the strings '13' and '30'. If you write them as dates, though, PostgreSQL will correctly tell you that '2011-04-26' (following the datestyle setting on my server) isn't in that range.
Second, I'm guessing that the odd out-of-range values appear because you're using an indeterminate expression in your aggregate. The expression WEEK(pt.timestamp) doesn't appear in the SELECT list. I think every other SQL engine on the market will throw an error if you try to do that. Since it's not in the SELECT list, MySQL will return an apparently random value from that aggregate range.
To avoid these kinds of errors, don't do string comparisons on date or timestamp ranges, and don't use indeterminate aggregate expressions.
Posting DDL and minimal SQL INSERT statements to reproduce the problem helps people help you.
I'm absolutely not sure, but it is maybe the comparison is done as a string and not as a date.
DATE_FORMAT returns a string and both your condition are strings too.
You should try without the DATE_FORMAT, just the column, or maybe trying to convert the condition to a date.
I'm thinking something like this :
pt.timestamp BETWEEN STR_TO_DATE('13/05/11', '%e/%m/%y') AND STR_TO_DATE('30/05/11', '%e/%m/%y')
I am pretty sure you are meaning to do
WHERE pt.timestamp BETWEEN TO_DATE('13/04/11', 'dd/mm/yy') AND TO_DATE('30/05/11', 'dd/mm/yy')
Before you are asking it for a string between two other strings.
Update
I think a few point is being missed here. Based on the calculations you are doing on pos_transactions.timestamp I am going to assume it's a type of timestamp. In your query you need to use the timestamp directly if you want to do a range compare. A timestamp already contains all the data you need to do this comparison. You don't need to covert it to Day/Month/Year to compare it.
What you need to do is this:
Find all values where my timestamp is between create a new date from '13/05/11' AND create a new date from '30/05/11'. pt.timestamp is already a timestamp, no need to convert it in your WHERE clause.
What you keep doing is converting it into a String representation. Thats ok when you want to display it, but not when you want to compare it with other values.