Select data range when time and date are concatenated - mysql

I am currently using the line below to get the date
WHERE DATE (DateTime) BETWEEN '2016-12-19' AND '2016-12-23'
12/12/2016 09:31 - this is the date and time format
But it keeps on returning everything in the table from 2014.
The statement above seems to only work when its a short query but when I add a few lines to the SQL query it doesn't seem to work, Its extracting all dates in the table.
SELECT phone_number,system_outcome,DateTime
FROM calls
WHERE DATE (DateTime) BETWEEN '2016-12-19' AND '2016-12-23'
AND system_outcome = 'ANSWER_MACHINE'
GROUP BY phone_number
HAVING count(Phone_number) > 6

You need to learn to store dates in the correct format, not as a string. You can fix your where clause using date_format():
where date_format(left(date, 10), '%m/%d/%Y') between '2016-12-19' AND '2016-12-23'
I should also note that if you want phone numbers, then all other attributes should be the arguments of an aggregation function. Say:
SELECT phone_number, system_outcome, group_concat(DateTime)
FROM calls
WHERE date_format(left(date, 10), '%m/%d/%Y') BETWEEN '2016-12-19' AND '2016-12-23' AND
system_outcome = 'ANSWER_MACHINE'
GROUP BY phone_number, system_outcome
HAVING count(Phone_number) > 6;

Related

mysql date conversion returns null converting certain months

I have this query (take a look on between dates):
SELECT user_name, COUNT(*) AS 'COUNT'
FROM user_records
WHERE date_created between (STR_TO_DATE('11/24/2020','%m/%d/%y'))
and (STR_TO_DATE('12/26/2021','%m/%d/%y'))
GROUP BY user_name ;
The select is between dates:
startDate: (STR_TO_DATE('11/24/2020','%m/%d/%y'))
finishDate: (STR_TO_DATE('12/26/2021','%m/%d/%y'))
This query will return something because there are records on year 2020
the problem is when i change the month of the finishDate, i tried with:
finishDate: (STR_TO_DATE('1/26/2021','%m/%d/%y')) = null
finishDate: (STR_TO_DATE('01/26/2021','%m/%d/%y')) = null
finishDate: (STR_TO_DATE('10/26/2021','%m/%d/%y')) = null
It just makes no sense... im using mysql community 8.0.20
Since the problem only occurs in the finsihDate perhaps this could be helpful.
SELECT user_name, COUNT(*) AS 'COUNT'
FROM user_records
WHERE date_created between (STR_TO_DATE('11/24/2020','%m/%d/%y'))
and (DATE_ADD(STR_TO_DATE('11/24/2020','%m/%d/%y'), INTERVAL 367 DAY))
GROUP BY user_name ;
Of course you should check for relevant errors or warnings in MySQL server logs, that could explain the problem for finsihDate.
********UPDATE SOLUTION:
for some unknown reason my db IDE shows the date with this format "$DAY/$MONTH/$YEAR" even if insert the right DATE MYSQL FORMAT ("$YEAR-$MONTH-$DAY)
i got the following warnings:
And this is the final query that worked but your solution did worked as well:
SELECT user_name, COUNT(*) AS 'COUNT'
FROM user_records
WHERE date_created between '2020-11-24' AND '2021-01-24'
GROUP BY user_name ;
The problem with your query is the date format. Lowercase '%y' matches a two digit year. So, only the first two characters from 2021 are used for the year -- and you have the wrong year.
But, that is not the real problem. You don't need str_to_date(). Just use properly formatted date literals.
Assuming that the dates are stored correctly as date data types, then you can simply use:
SELECT user_name, COUNT(*) AS COUNT
FROM user_records
WHERE date_created between '2020-11-24' and '2021-12-26'
GROUP BY user_name ;
If date_created is stored as a string, then fix your data model so it is either a date or datetime. Dates should not be stored as strings.

Why can't I just group by date(startTime) here?

I have a date/time field in my table called startTime.
I would like the output as follows:
select
YEAR(startTime),
MONTH(startTime),
DAY(startTime),
dayofmonth(startTime),
startTime,
...
This is fine, and I only have to group by startTime.
However, for my output, I am only really interested in the date part of the startTime.
So I changed my output to be
select
YEAR(startTime),
MONTH(startTime),
DAY(startTime),
dayofmonth(startTime),
DATE(startTime),
...
When I try to run this, SQL makes me group by Year, Month, day, dayofmonth and date(startTime).
This seems to be a quirk of the date() function?
I thought maybe it's due to the time part of the startTime field, but Year, Month, Day and dayofmonth are no more granular than a date so I am confused as why I have to group by those.
Any insights greatly appreciated!
My code currently:
YEAR(startTime),
MONTH(startTime),
DAY(startTime),
dayofmonth(startTime),
date(startTime),
count(id)
from
bookings
group by 1, 2, 3, 4, 5
in your select statement we must have distinct values of selected column (as a group) for every distinct value given value of what we group them by.
For example if you have startime in your select clause, and also in group by clause, we get distinct values of selected attributes - date, month, year, & startTime for every unique value of starttime. But if you remove starttime from select clause, the attributes selected are no longer guaranteed to be unique.
Consider 2 startTime values 2020-03-12T01:01:01.000UTC and 2020-03-12T02:02:02.000UTC its expected to produce two rows if we group by startTime (as two distinct startTimes), but the selected values for year, month and date would be same in both of these rows (as they differ only in time part) which is breaking the group by contract.
Hence we can only have group of attributes in select clause which MUST provide a different value for every combination of attributes in the group by clause.

Mysql date range does not return correct range

Here is my code:
select date_format(fee_month, '%b-%Y') from bb_fee_info where
date_format(`FEE_MONTH`,'%b-%Y') >= 'Apr-2016'
and date_format(`fee_month`, '%b-%Y') <= 'Apr-2017'
As per my understanding above statement should return from April-2016 to April-2017 but it only returns April-2017 records why is that ?
FYI in my Table fee_month stored as date data type and for example, for April month records all my fee_month will be stored as 2017-04-01.
Could you try comparing the dates directly instead, e.g.:
SELECT DATE_FORMAT(fee_month, '%b-%Y')
FROM bb_fee_info
WHERE fee_month BETWEEN '2016-04-01' AND '2017-04-01';
If you can't change the argument type/format then you can convert it into date using STR_TO_DATE and do the comparison, e.g.:
SELECT DATE_FORMAT(fee_month, '%b-%Y')
FROM bb_fee_info
WHERE fee_month BETWEEN STR_TO_DATE(CONCAT('01-', 'Apr-2016'),'%d-%M-%Y') AND STR_TO_DATE(CONCAT('01-', 'Apr-2017'),'%d-%M-%Y')

SQL query to select data between dates does not show last date

im using a query to get data between dates but for some reason it does not pull the data of the last date selected here is my query:
SELECT * FROM order WHERE status = "completed" AND orderdate >= ? AND orderdate <= ? ORDER BY orderid DESC
Im using is equal to or less then... but still?
what am i doing wrong ?
SELECT * FROM order WHERE status = "completed" AND date(orderdate) >= date(?) AND date(orderdate) <= date(?) ORDER BY orderid DESC
It happened with me also, but in my case instead of passing a date I was querying using a datetime variable, Please make sure you are querying with date variable only.
Make sure that orderdate is date as well as your query parameter is also date, or use appropriate function to convert them in date, than query.
Your dates are actually datetimes - so you are actually, in the case of the upperbound, saying "12 midnight" on whichever date you choose. Hence, if it tries to test a value at say 10am in the morning, it fails as being outside the range.
Either set the upperbound date one day forward, or explicitly only test the date part of the datetime...

Retrieving all records based on a specific month in MySQL

my dates in my table are strings in the format:
"10/12/2009"
Now how would one get all the records from a month, lets say June (number "6" being provided)?
Check the MySQL function STR_TO_DATE.
You should not store dates as string, however. Use the type DATE.
The short answer to your question is that you can use the STR_TO_DATE and MONTH functions to 1) convert the string representation into a DATE, and 2) extract the month component from the date:
SELECT t.*
FROM mytable t
WHERE MONTH(STR_TO_DATE(t.dateasstringcol,'%M/%d/%Y')) = 6
(This is assuming here that by '10/12/2009', you are specifying Oct 12, and not Dec 10. You'd need to adjust the format string if that's not the case.)
Alternatively, if month is indeed the leading part of the date, you could do a simple string comparison, if the month is the leading component:
SELECT t.*
FROM mytable t
WHERE t.dateasstringcol LIKE '6/%'
OR t.dateasstringcol LIKE '06/%'
(You could eliminate one of those predicates, if you have an exact format specified for the striing value representing the date: either if month is always stored as two digits -OR- the month is never stored with a leading zero.)
If you are passing in an argument for the month, e.g. '6', then you could construct your statement something like this:
WHERE t.dateasstringcol LIKE '6' + '/%'
If month is the second component of the date, then you could use:
SELECT t.*
FROM mytable t
WHERE t.dateasstringcol LIKE '%/' + '6' + '/%'
OR t.dateasstringcol LIKE '%/' + '06' + /%'
NOTE:
All of the previous example queries will return rows for June of any year (2009, 2010, 2011)
You can extend those examples, and do something similar with the year, using the YEAR function in place of the MONTH function, or for string comparison
AND t.dateasstringcol LIKE '%/%/2011'
Normally, we'd extract rows for a particular month for a particular year, using a date range, for example:
SELECT t.*
FROM mytable t
WHERE MONTH(STR_TO_DATE(t.dateasstring,'%M/%d/%Y')) >= '2011-06-01'
AND MONTH(STR_TO_DATE(t.dateasstring,'%M/%d/%Y')) < '2011-07-01'
Of course, when the date value is stored as a DATE datatype rather than as a VARCHAR, this means we don't need the STR_TO_DATE and MONTH functions, we can specify a comparison to the native DATE column. This approach allows us to make use of an index on the date column, which can improve query performance on large tables.
SELECT t.*
FROM mytable t
WHERE t.realdatecol >= '2011-06-01'
AND t.realdatecol < '2011-07-01'
The STR_TO_DATE function is your friend here:
SELECT * FROM my_table
WHERE STR_TO_DATE('10/12/2009','%M/%d/%Y') >= '2012-06-01';
MONTH should help here if we want current month or particular month data. e.g:
$month = date('m'); OR particular month.
SELECT * FROM users WHERE MONTH(str_to_date("10/12/2009",'%e/%m/%Y')) = $month;