Quantcast
Channel: Brent Ozar Unlimited®
Viewing all articles
Browse latest Browse all 3153

Getting Started With Oracle: Date Math

$
0
0

As soon as you store a date value

Someone is going to want to do something with it. Bucket it into a 30/60/90 day window, figure out how many times something happened between it and current, filter on it, or send you creepy anonymous cards on your birthday full of doll hair and coupons for lotion.

Since Oracle is apparently no slouch, it can do all this stuff for you. No more awkwardly counting days on your fingers or messing up your day-at-a-time Far Side desk calendar trying to look 6 months into the future. Not for you, smarty pants. We’re gonna use some SQL.

Just like home

If you add a number to a date value, Oracle adds that many days to the date. It’s exactly the same as GETDATE() + whatever in SQL Server. Below will add and subtract 365 days from the hire date of each employee.

SELECT 
HIRE_DATE, 
HIRE_DATE + 365,
HIRE_DATE - 365
FROM HR.EMPLOYEES;
Check out those headers!

Check out those headers!

One thing I really like that Oracle does, that SQL Server doesn’t do, is replace calculated column headers with the syntax behind them. It can be annoying if there’s really long or complicated syntax behind it, but it’s generally nicer to have something there. SQL Server just says “No column name” when you do the same thing. Both scenarios bring their own good reasons to alias columns to the table. Get it? Table. HEH!

One big difference you’ll find is that adding or subtracting two date values in Oracle leaves you with a number, not a date. The number you’re left with is the number of days between the two days.

SELECT FIRST_NAME, HIRE_DATE, SYSDATE, SYSDATE - HIRE_DATE
FROM HR.EMPLOYEES;
This is some old sample data.

This is some old sample data.

It’s really easy to get the number or months between two dates, or add months to a date. You can use the MONTHS_BETWEEN and ADD_MONTHS functions to do that.

SELECT FIRST_NAME, MONTHS_BETWEEN(SYSDATE, HIRE_DATE) AS "A LONG TIME"
FROM HR.EMPLOYEES;

SELECT FIRST_NAME, HIRE_DATE, ADD_MONTHS(HIRE_DATE, 12) AS "FIRST ANNIVERSARY"
FROM HR.EMPLOYEES;

These are areas where I think SQL Server is a bit ahead of Oracle. DATEADD and DATEDIFF offer you a lot more flexibility and range of motion to pull out or add different intervals. I know there are Oracle workarounds with some additional math operators, but they’re not as straightforward to me.

A couple other neat options are NEXT_DAY and LAST_DAY. Next day tells you the next time the day of the week you choose occurs after the date you pass in, and LAST_DAY gives you the last day of the month for the date you pass in.

The NEXT_DAY function would be useful in a situation where the Monday following someone getting hired, they had to get their picture taken for their badge, or whatever.

SQL Server has EOMONTH (2012+), but curiously, neither platform has FIRST_DAY, or SOMONTH functions, to give you the first day of the month. That seems odd to me considering the amount of syntax that goes into getting back to the first day of the month (SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, @date), 0)).

You can also add years and months to a date using the TO_YMINTERVAL function. Um. Confetti?

SELECT EMPLOYEE_ID, HIRE_DATE, NEXT_DAY(HIRE_DATE, 'MONDAY') AS "FOLLOWING_MONDAY"
FROM HR.EMPLOYEES;

SELECT EMPLOYEE_ID, HIRE_DATE, LAST_DAY(HIRE_DATE)
FROM HR.EMPLOYEES;

SELECT EMPLOYEE_ID, HIRE_DATE, HIRE_DATE + TO_YMINTERVAL('10-00') AS "TENTH_ANNIVERSARY"
FROM HR.employees;

Finally, if you need to get individual parts of a date, you can use the EXTRACT function:

SELECT EMPLOYEE_ID,HIRE_DATE,
EXTRACT(DAY FROM HIRE_DATE),
EXTRACT(MONTH FROM HIRE_DATE),
EXTRACT(YEAR FROM HIRE_DATE)
FROM HR.EMPLOYEES;

This is pretty close to the DATEPART function in SQL Server.

Rudimentary Can’t Fail

Both Oracle and SQL Server store dates and times in the same way, though the way they’re presented and some of the ways we work with them vary between the two platforms. They’re not too far off from each other, and both have strengths and weaknesses. SQL Server makes it really easy to pass in dates, but Oracle is far less ambiguous about which dates it will compare, which can be error prone. Either way, if you’re developing an application to work with either platform, or if you need to port code over, you have your work cut out for you when it comes to working with dates.

Thanks for reading!

Brent says: those headers, are you kidding me? It puts the plain English formula as the field name? That’s amazing.

Join us in person for The Senior DBA Class or SQL Server Performance Tuning.


Viewing all articles
Browse latest Browse all 3153

Trending Articles