mysql date direct subtraction - mysql

I have a two date columns, dateA and dateB. If I subtract dateA from dateB (dateB - dateA), I get wrong results but not using DATEDIFF(dateB,dateA)function. I get wrong result from direct subtraction when used in a table with data but not with below query.
SELECT DATE('2013-01-31') - DATE('2013-01-27')
Why?
EDIT:
I found that in MySQL if the two dates are within a month then direct subtraction gives correct result but if the dates span month, year there might be a problem.
Am I right?

Presumably, you columns are not stored as dates, but as strings. If they were stored as dates, then subtraction would work as expected.
When you subtract two strings, such as:
SELECT '2013-01-31' - '2013-01-27'
Then MySQL converts them to numbers, based on the leading digits. In this case, both start with the numbers 2013, so both are converted to 2013 (if there were no digits at the beginning then the value would be 0). These numbers are then subtracted.

Are your column's defined as date, or as Varchars? Because Date as a String means nothing. When you do a DATE('2013-01-31'), it creates a date object and hence the subtraction works. So, if your column is defined as Varchar, do DATE(dateB) - DATE(dateA).

Related

Difference between two dates in MySQL with DATE() function

I am using DATE() function to calculate the difference between two dates in MySQL
value of SYSDATE() function is following
select SYSDATE();
2020-07-15 12:16:07.0
When I am using date from same month, it is giving correct result
select DATE(SYSDATE())- DATE('2020-07-13');
2
But when I am using date from last month it is giving difference as 86 instead of 16;
select DATE(SYSDATE())- DATE('2020-06-29');
86
Edit:
I am aware that we can use DATEDIFF() but I want to verify why DATE() function is giving results like this since we are already using this in code
MySQL doesn't support subtracting one date from another. The code
SELECT DATE '2020-07-15' - DATE '2020-06-29';
should hence result in an error, but MySQL silently converts this to this instead:
SELECT 20200715 - 20200629;
Seeing that you want to subtract two values, it assumes that you want to work with numbers. Dates are not numbers, but their internal representation yyyymmdd can be represented numerically. So, while CAST(DATE '2020-07-15 ' AS int) fails with a syntax error, as it should, MySQL is not consistent, when it comes to subtraction. It generates the numbers 20200715 and 20200629 and works with these.
I consider this a bug. MySQL should either raise an exception or return an INTERVAL when subtracting one DATE from another.

Sql search Result between two dates

i have a table name expected expense in which i have 4 columns name Expense_title, Amount, expense_category, date and all the 4 columns have var char type. When I try to find expense between two dates it work fine for same year, e.g. 11/27/2018 and 12/27/2018, but it doesn't get any result when I try to find expense between two years, e.g. 12/27/2018 And 01/27/2019. please help
I am trying this query
SELECT *
from expected_expense
WHERE Date BETWEEN '$start_date' AND '$end_date'
As per the comments, this is because of the varchar type.
The between operator is nothing different than doing two closed inequalities for its range limits. In your example,
between 12/27/2018 And 01/27/2019
will be changed internally to
>= 12/27/2018 and <= 01/27/2019
but these are not dates, they are text. And the second one is less than the first, so nothing will be returned. It's like asking the question: which letter comes after q but before b? None.
Either change the fields to datetime, or use conversion functions in your query.

Casting negative integer to DATE in SQL

I'm having a problem working with a Navicat Database. I got a column in SQL called fechaNacimiento (Birthdate) that should be a Date type, but instead it's stored as integers (most negative integers):
SELECT fechaNacimiento FROM Registrados
And I'm getting:
fechaNacimiento
-1451678400
-2082829392
-1798746192
-1199221200
-1356984000
-694299600
-1483214400
-1924976592
-1830368592
-2019670992
-1678909392
239252400
1451617200
-879541200
I don't know how this dates where loaded, I just know that inside that negative integer there's a date, and nobody here have any clue about how to spell SQL, so I have nobodoy to ask. If I just cast it to DATETIME, I get all of them as NULL values. Any idea in how to convert this data to Date type?
Numbers like that make me think of Unix times, number of seconds since 1970. If so, you might be able to do:
select dateadd(second, <column>, '1970-01-01')
This would put the negative values sometime before 1970 (for instance, -1678909392 is 1916-10-19). If you have older dates, then that might be the format being used.
These might also be represented as milliseconds. If so:
select dateadd(second, <column>/1000, '1970-01-01')
In this case, -1678909392 represents 1969-12-12.
In MySQL, you would use:
select '1970-01-01' + interval floor(column / 1000) second

why i cant return rows between two dates with timestamp correctly

how to return exactly rows between two dates with timestamps
this code didn't return all row between 01-04 and 07-05
so what is the problem and why it didn't work correctly
and how to select rows between two date with timestamp when i use date
format like this 01-04-2015
SELECT d_send_items.si_id ,
DATE_FORMAT(FROM_UNIXTIME(d_send_items.si_send_date), '%d-%m-%Y')
FROM d_send_items WHERE
DATE_FORMAT(FROM_UNIXTIME(d_send_items.si_send_date), '%d-%m-%Y') BETWEEN '01-04-2015' AND '07-05-2015'
date_format returns a string, so between is using string comparisons to figure out whether the values are between those two you provide.
So, unless your date format is something like yyyy-mm-dd, between is not going to work as you expect.
For example, the date 08-04-2015 is between the two dates 01-04-2015 and 07-05-2015 but the string 08-04-2015 is not between the two strings 01-04-2015 and 07-05-2015, because the most significant portion 08 is beyond the range which terminates at 07....
So you could use:
where
date_format(from_unixtime(d_send_items.si_send_date), '%Y-%m-%d')
between '2015-04-01' and '2015-05-07'
but per-row functions never scale well in relational databases.
If they're proper timestamp fields, I think you can also bypass the conversion and use something like:
where d_send_items.si_send_date >= '01-04-2015'
and d_send_items.si_send_date < '08-05-2015'
(noting the < day following bit for the second conditional since 08-05-2015 is the same as 08-05-2015 00:00:00) assuming MySQL will recognise those date formats as dd-mm-yyyy.
However, even if it doesn't and you have to use some function to turn those string into timestamp values, this is something that would be done once for the whole query rather than (most likely) for every single row.

MySQL: Modifying output of a field for calculation

I know calculating age from DOB is relatively simple but I have an issue with different data entry formats in the database. Also, I know this can be easier using PHP, but I don't know PHP and only have MySQL to work with.
The DOB entered into the DB is entered as "month/day/year" or "00/00/0000". But when calculating against today's date, the date would be formatted as "year-month-day" or "0000-00-00". Furthermore, the month placed in the DOB field can have either a one number month (1/01/1999) or a two number month (01/01/1999), so it's not consistent.
I am trying to use the below to utilize CONCAT, SUBSTRING and LOCATE to output the DOB in a better suited format for the age calculation. I think I'm close but not quite there. Any help would be very much appreciated.
SELECT
CONCAT(SUBSTRING(APPU_DOB,-4,4),'-', SUBSTRING(APPU_DOB,LOCATE('/', APPU_DOB),1),'-',SUBSTRING(APPU_DOB,4,2))
FROM APPU_APP_USER
JOIN APPL_APP ON APPU_APPL_ID = APPL_ID
WHERE DATE_FORMAT(APPL_CREATE_DT, '%Y-%M-%D') >= '2014-01-01';
Instead of Concat use str_to_date function.
select str_to_date( appu_dob, '%m/%d/%Y' ) as 'dob';
on 1/01/1999 it returns a valid date formatted object with value 1999-01-01.
You can use it on other date strings that have single or two digit day or month numbers.
Note: To represent or refer a month, use small case m but not capital M, in the format pattern string.
And you should better redefine the data type of appu_dob field to date. So that you can easily apply date specific functions on it for any calculations.