DATE/TIME Functions in SQL. Tutorial on how to use CAST, EXTRACT... | by Jason Lee | Towards Data Science

Working with dates and times is a common practice when working in SQL. Using dates, we can calculate changes over time, trends in the data, perform interval arithmetic. To better understand the impacts of the underlying business problem.
“time-series data” as a sequence of data points, measuring the same thing over time, stored in time order.
Some common uses of time-series data
Stock price movement
Sensor tracking (e.g., weather tracking)
Rental services (e.g., bike or scooter rentals)
For this tutorial, I will assume you have intermediate SQL skills. We will be covering three functions and working with PostgreSQL syntax.
CASTEXTRACTDATE_TRUNC
CAST
EXTRACT
DATE_TRUNC
Each of these functions can be useful when breaking down datasets with a lot of data. We will see the benefits of each one as we go through the code with some examples.
A CAST function converts the selected data type into another. Pretty straight forward. It changes one type into your preferred type. The syntax is below.
CAST(expression AS datatype)
Below is an example of how it can be applied to date and time.
SELECT    NOW(),    CAST(NOW() AS TIMESTAMP),    CAST(NOW() AS DATE),    CAST(NOW() AS TIME),    CURRENT_DATE,    CURRENT_TIME
In this query, we expect to have 6 outputs. If you are unfamiliar with NOW(), CURRENT_DATE, CURRENT_TIME they are SQL functions that retrieve the current time or date. Below are all the outputs from the query in order. (note — you will get different numbers since the functions call the exact time or date)
2020–03–28 23:18:20.261879+00:00
2020–03–28 23:18:20.261879
2020–03–28
23:18:20.261879
2020–03–28
23:18:20.261879+00:00
Looking at the first result from the NOW() used on its own, we get a full timestamp value, including the timezone. Now as we go down to the second output, we used CAST to only retrieve the TIMESTAMP, which does not include the timezone from the NOW(). Now we can see how cast works. We pass in a value we want to be converted and then state the type we want.
Next, we use CAST() on NOW() but pass in DATE as our desired type. We now get a timestamp stripped to only the year/month/day format. Similarly, look at the CAST() function with NOW() and only TIME, and we get just the time value with no date.
We can see how the CAST function works with time, and the last two outputs using CURRENT_DATE and CURRENT_TIME are just there for you to see the comparison of results.
SQL also allows CAST() functions to be used with types that are not timestamped.
SELECT     CAST(1.34 AS INT),    CAST(1 AS BOOLEAN),    CAST(2.65 AS DEC(3,0))
The results from this query are,
1 → Since an integer can’t have decimals, it will round to the nearest integer value
true → 1 as a boolean is true, and 0 is false
3 → using the DEC() we can also do the reverse of our first integer CAST.
In SQL, you can also use INTERVAL to add more time to any timestamp you have. For the examples below, you don't need to use the CAST() function, but I've chosen to do so only to have the date.
SELECT    CAST(NOW() AS DATE) AS TODAY_DATE,    CAST((INTERVAL '3 DAYS' + NOW()) AS DATE) AS three_days,    CAST((INTERVAL '3 WEEKS' + NOW()) AS DATE) AS three_weeks,    CAST((INTERVAL '3 MONTHS' + NOW()) AS DATE) AS three_months,    CAST((INTERVAL '3 YEARS' + NOW()) AS DATE) AS three_years
We can see that using the INTERVAL in addition to the length of the interval in days, weeks, months or years adds more time to whatever date you have — in this example the current date is obtained from NOW().
Next, we can look at pulling a specific format out of a timestamp. The goal is to extract a portion out of a timestamp. For example, if we want just the month from the date 12/10/2018, we would get December (12).
Let’s take a look at EXTRACT syntax
EXTRACT(part FROM date)
We state the type of extraction we want as part and then the source to be extracted date. EXTRACTis an import tool in time series data analysis. It helps you isolate groups in your timestamps to aggregate data based on precise timings. For example, if a car rental store wanted to find the busiest rentalHOUR on MONDAYS every MAY, you can do that with EXTRACT. You can drill down the details and see more valuable insights.
Let’s assume we run NOW() and our timestamp is 2020–03–29 00:27:51.677318+00:00, we can use EXTRACTto get the following.
SELECT    EXTRACT(MINUTE      FROM NOW()) AS MINUTE,    EXTRACT(HOUR        FROM NOW()) AS HOUR,    EXTRACT(DAY         FROM NOW()) AS DAY,    EXTRACT(WEEK        FROM NOW()) AS WEEK,    EXTRACT(MONTH       FROM NOW()) AS MONTH,    EXTRACT(YEAR        FROM NOW()) AS YEAR,    EXTRACT(DOW         FROM NOW()) AS DAY_OF_WEEK,    EXTRACT(DOY         FROM NOW()) AS DAY_OF_YEAR,    EXTRACT(QUARTER     FROM NOW()) AS QUARTER,    EXTRACT(TIMEZONE    FROM NOW()) AS TIMEZONE
We see that we can go into great detail in how we want to extract information out of our timestamps. Note — DOW — The day of the week is Sunday(0) to Saturday(6).
We can build on the rental car example earlier and see how it would work.
SELECT   EXTRACT(HOUR FROM RENTAL_DATE) AS HOUR,   COUNT(*) as RENTALS FROM RENTAL WHERE    EXTRACT(DOW   FROM RENTAL_DATE) = 1 AND    EXTRACT(MONTH FROM RENTAL_DATE) = 5GROUP BY 1ORDER BY RENTALS DESC
Remember we want the busiest rentalHOUR on MONDAYS every MAY . First, we use EXTRCT in the SELECT to state, we want only the HOUR and the total COUNT . We then pass in two EXTRACT functions for in the WHERE clause to filter only MONDAYS and MAY. Looking at the table below 11 am is the most popular rental time every Monday in May with a total of 11 rentals.
Truncate — to shorten by or as if by cutting off
The purpose of truncating a date in SQL is to return an interval at an absolute precision. The precision values are a subset of the field identifiers that can be used with the EXTRACT. DATE_TRUNC will return an interval or timestamp rather than a number.
The syntax for DATE_TRUNC, time_column is the database column that contains the timestamp you'd like to round, and ‘[interval]’ dictates your desired precision level.
DATE_TRUNC(‘[interval]’, time_column)
Let’s assume our NOW() returns the same 2020–03–29 00:27:51.677318+00:00, we can use date_part to get the following.
SELECT    CAST(DATE_TRUNC('DAY', NOW()) AS DATE) AS DAY,    CAST(DATE_TRUNC('WEEK', NOW()) AS DATE) AS WEEK,    CAST(DATE_TRUNC('MONTH', NOW()) AS DATE) AS MONTH,    CAST(DATE_TRUNC('YEAR', NOW()) AS DATE) AS YEAR
Think of using DATE_TRUNC as getting the interval of where it is currently, and each level of an interval is how the date gets trimmed. Note — we did not need to use CAST in this example. I used it to ensure the format was clean for analysis.
We can use DATE_TRUNC on the rental car scenario from earlier, and try to find which day in the year regardless of time is more popular for rentals.
SELECT    CAST(DATE_TRUNC('DAY', RENTAL_DATE) AS DATE) AS RENTAL_DAY,    COUNT(*) AS RENTALSFROM RENTALGROUP BY    RENTAL_DAYORDER BY RENTALS DESC
Now that we have seen how to use CAST, EXTRACT, and DATE_TRUNC we can bring together some of the techniques we learned into one practical example.
For this example, we will add a new time function called AGE — which takes in 2 dates as an argument and outputs the "AGE" or the time in years and months between the dates.
Let’s wrap up this tutorial by extracting a list of customers who had the longest rental duration ( AGE ) from 2019–05–01 + 30 days.
SELECT    CUSTOMER_ID,    EXTRACT(DOW FROM RENTAL_DATE) AS DAY_OF_WEEK,    AGE(RETURN_DATE, RENTAL_DATE) AS RENTAL_DAYSFROM    RENTALWHERE     RENTAL_DATE         BETWEEN CAST('2019-05-01' AS TIMESTAMP) AND                CAST('2019-05-01' AS TIMESTAMP) + INTERVAL '30 DAY'ORDER BY 3 DESC
I hope you feel comfortable working with timestamps in SQL. You have learned to use CAST , EXTRACT, INTERVAL,DATE_TRUNC , and AGE. You should be well equipped to tackle trend related analysis, and dive deeper into the data to find insights you may not have been able to find before!
If you are interested in more SQL tutorials, check out my other posts.
How to use CTEs in SQL
Introduction to Window Functions
Creating Tables in SQL
Connect with me on Linkedin or Github