Number of days between two dates - ANSI SQL - sql

I need a way to determine the number of days between two dates in SQL.
Answer must be in ANSI SQL.

ANSI SQL-92 defines DATE - DATE as returning an INTERVAL type. You are supposed to be able to extract scalars from INTERVALS using the same method as extracting them from DATEs using – appropriately enough – the EXTRACT function (4.5.3).
<extract expression> operates on
a datetime or interval and returns an
exact numeric value representing the
value of one component of the datetime
or interval.
However, this is very poorly implemented in most databases. You're probably stuck using something database-specific. DATEDIFF is pretty well implemented across different platforms.
Here's the "real" way of doing it.
SELECT EXTRACT(DAY FROM DATE '2009-01-01' - DATE '2009-05-05') FROM DUAL;
Good luck!

I can't remember using a RDBMS that didn't support DATE1-DATE2 and SQL 92 seems to agree.

I believe the SQL-92 standard supports subtracting two dates with the '-' operator.

SQL 92 supports the following syntax:
t.date_1 - t.date_2
The EXTRACT function is also ANSI, but it isn't supported on SQL Server. Example:
ABS(EXTRACT(DAY FROM t.date_1) - EXTRACT(DAY FROM t.date_2)
Wrapping the calculation in an absolute value function ensures the value will come out as positive, even if a smaller date is the first date.
EXTRACT is supported on:
Oracle 9i+
MySQL
Postgres

Related

What is the alternative of datefromparts in Presto (AWS Athena)

What is the best performance alternative of datefromparts SQL function in AWS Athena (Presto DB)?
The use case is:
I have the date parts (i.e. the day, month, and year) and need the date from these.
You would typically use parse_date(), with the proper format specifiers. If your date is in ISO format, you can directly use from_iso_date() (or from_iso_timestamp()).
On the other hand, if you need to extract dates part, you can use extract(), like:
extract(hour from current_timestamp)
Note that Presto also offers a full range of short function name that correspond to the possible extraction parts: year(), quarter(), month(), ...

Problems with BETWEEN dates operator

I am practising and experimenting with different syntax of SQL BETWEEN operator in regards to dates from the "https://www.w3schools.com/sql/sql_between.asp"
This is the Order table in my database:
LINK: https://www.w3schools.com/sql/sql_between.asp
The query is fetching the orderdates between a given condition of 2 dates.
These are the two main syntax versions (according to w3schools):
SELECT *
FROM Orders
WHERE OrderDate BETWEEN #01/07/1996# AND #31/07/1996#;
and:
SELECT *
FROM Orders
WHERE OrderDate BETWEEN '1996-07-01' AND '1996-07-31';
The output that we get on typing the above two queries from the Orders table
Number of Records: 22 (out of 196 records). Yes this is correct.
Now I am experimenting with this syntax versions.
CASE #1:
SELECT *
FROM Orders
WHERE OrderDate BETWEEN #1996/07/01# AND #1996/07/31#;
Result of case #1: 22 (same as the above syntax)
In the SQL try it out editor(https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_between_date&ss=-1) they are stating that this SQL statement is not supported in the WebSQL database.The example still works, because it uses a modified version of SQL.
WHY SO?
If you're using the W3Schools Tryit editor in Chrome, you're using WebSQL, which is basically SQLite.
SQLite doesn't have a date/time format, so is probably storing the date values as strings formatted in the ISO-8601 format (see this answer for more information).
Other database systems (e.g. Oracle, Microsoft SQL Server, Postgres, MySQL) have built-in date formats, and you generally represent them as strings (enclosed in single quotes). For example: '1997-07-01' (depending on the specific RDBMS, there might be more specific considerations).
The format that uses pound signs (e.g. #7/1/1997#) is unique to Microsoft Access (see this answer for more information).
Bottom line: Dates are generally enclosed in single quotes. You're best off sticking to the ISO-8601 standard (e.g. 1997-07-01).
If you're learning SQL, there are other resources out there besides W3Schools. I would recommend downloading an open-source RDBMS like Postgres or MySQL, setting up a sample database, and working on some queries. Challenge sites like codewars might also be helpful
One more thing: Don't use BETWEEN for dates. Use >= and <, to make sure you're not excluding dates with a time portion. For more information, read this blog.

Does SQL has some standard data-time function cross database?

Does SQL has some standard data-time function cross database? Such as :
extract year, month, day, hour, minute or second
format to specific formatter
parse from string
I believe the answers are yes, no, and no.
The extraction functions are extract(<whatever> from date). I don't think there is a standard for parsing and formatting. However, to_char() and to_date() are used across multiple databases.

SQL WHERE Clause condition evaluation

I have an easy question, however I couldn't find the answer for this. In SQL WHERE clause which is better?
TO_CHAR (DAT, 'YYYYMMDD') BETWEEN '20080101' AND '20131231'
or
DAT BETWEEN TO_DATE('20080101','YYYYMMDD') AND TO_DATE('20131231','YYYYMMDD')
Are the condition values evaluated only once and then tested for every row in the table, or does the SQL engine recalculate it every time?
Any argument that involves constants and literals will only be evaluated once. The second, however, is much better - it allows you to index the dat column and then use this index to improve performance, while the first query will not allow the index to be used.
And here's the BEST :
WHERE DAT BETWEEN '2008-01-01' AND '2013-12-31'
SQL has literals for date/time types too so there just isn't any need to invoke any of these scalar functions.
BTW you tagged the question SQL. That means your question relates to standard SQL, not to any particular engine and/or its implemented dialect (hover over the tag and read what it says). The standard mandates the date format used in this example. Specific engines might support additional formats for date literals, e.g. '12/31/2013' or '31.12.2013'.

Sql Ansi to manage DateTime values

I'm developing a multi-database system.
I want the difference between two dates in seconds.
In SQL Server I got:
DATEDIFF(second,stardate,enddate)
In MySql:
TIME_TO_SEC(TIMEDIFF(stardate,enddate))
My question:
Does Sql Ansi have functions to manage DateTime values? i.e.: There are datetime functions generic for all databases?
According to SQL:1999, date1-date0 should give you a value of type INTERVAL, a struct from which you should be able to extract YEAR, MONTH, DAY, etc.
I've never used it and I don't think it's widely supported (though I may not be up-to-date). If you're doing time arithmetic in the database layer and you want to be cross-DBMS compatible the usual solution is simply to use integer timestamps (of whatever resolution, but Unix time is common) and plain old integer arithmetic which is completely reliable cross-platform.