Oracle SQL script to generate Date Dimension data for use in Microsoft Excel Data Models

Date dimension is that one dimension or business perspective without which an Excel Data Model cannot ever exist. Here is an Oracle SQL script to generate the data for a Date Dimension. All that you have to do is change the start date and end date values in the in the last line of the below SQL query and execute it. Try it and experience the magic..!! Please leave your suggestions, comments and any enhancements that you might want to see in this.

Here is the downloadable script on Oracle LiveSQL:

/***********************
Description: Date Dimension Data Generation
Date Created: 14/Nov/2016
Author: Balakrishna Sappa
************************/

CREATE OR REPLACE TYPE DATE_OBJ AS OBJECT(DATE_KEY VARCHAR2(8), DATE_DT DATE, DATE_TYPE VARCHAR2(10), DAY_OF_MONTH SMALLINT, CAL_DAY_OF_YEAR SMALLINT, DAY_OF_WEEK_FULL_NAME VARCHAR2(9)
, DAY_OF_WEEK_SHORT_NAME CHAR(3), CAL_MONTH_FULL_NAME VARCHAR2(9), CAL_MONTH_SHORT_NAME CHAR(3), CAL_MONTH_ENUM SMALLINT, CAL_QTR_NAME CHAR(2), CAL_QTR_ENUM SMALLINT, CAL_HYR_NAME CHAR(2)
, CAL_HYR_ENUM SMALLINT, CAL_YEAR INT, START_OF_MONTH DATE, END_OF_MONTH DATE);
CREATE OR REPLACE TYPE CALENDAR_DATES IS TABLE OF DATE_OBJ;
CREATE OR REPLACE FUNCTION UDF_CALENDAR_GENERATOR(START_DATE IN DATE, END_DATE IN DATE)
RETURN CALENDAR_DATES
IS
CALENDAR_DATE CALENDAR_DATES;
BEGIN
SELECT CAST(MULTISET(WITH RCTE_DATES (DATE_DT)
AS
(SELECT START_DATE AS DATE_DT
FROM DUAL
UNION ALL
SELECT DATE_DT + 1 AS DATE_DT
FROM RCTE_DATES
WHERE DATE_DT + 1 <= END_DATE
)
SELECT CAST(EXTRACT(YEAR FROM DATE_DT) AS CHAR(4)) || SUBSTR(’00’ || EXTRACT(MONTH FROM DATE_DT), -2,2) || SUBSTR(’00’ || EXTRACT(DAY FROM DATE_DT), -2, 2) AS DATE_KEY
, DATE_DT
, ‘DATE’ AS DATE_TYPE
, EXTRACT(DAY FROM DATE_DT) AS DAY_OF_MONTH
, CAST(TO_CHAR(DATE_DT, ‘DDD’) AS SMALLINT) AS CAL_DAY_OF_YEAR
, TO_CHAR(DATE_DT, ‘DAY’) AS DAY_OF_WEEK_FULL_NAME
, TO_CHAR(DATE_DT, ‘DY’) AS DAY_OF_WEEK_SHORT_NAME
, TO_CHAR(DATE_DT, ‘MONTH’) AS CAL_MONTH_FULL_NAME
, TO_CHAR(DATE_DT, ‘MON’) AS CAL_MONTH_SHORT_NAME
, EXTRACT(MONTH FROM DATE_DT) AS CAL_MONTH_ENUM
, ‘Q’ || TO_CHAR(DATE_DT, ‘Q’) AS CAL_QTR_NAME
, CAST(TO_CHAR(DATE_DT, ‘Q’) AS SMALLINT) AS CAL_QTR_ENUM
, ‘H’ || CASE WHEN EXTRACT(MONTH FROM DATE_DT) IN (1,2,3,4,5,6)
THEN 1
ELSE 2
END AS CAL_HYR_NAME
, CASE WHEN EXTRACT(MONTH FROM DATE_DT) IN (1,2,3,4,5,6)
THEN 1
ELSE 2
END AS CAL_HYR_ENUM
, EXTRACT(YEAR FROM DATE_DT) AS CAL_YEAR
, TRUNC(DATE_DT, ‘MONTH’) AS START_OF_MONTH
, TRUNC(ADD_MONTHS(DATE_DT, 1), ‘MONTH’)-1 AS END_OF_MONTH
FROM RCTE_DATES
UNION
SELECT ‘999999’ AS DATE_KEY
, TO_DATE(’31-DEC-9999′, ‘DD-MON-YYYY’) AS DATE_DT
, ‘NA’ AS DATE_TYPE
, 0 AS DAY_OF_MONTH
, 0 AS CAL_DAY_OF_YEAR
, ‘NA’ AS DAY_OF_WEEK_FULL_NAME
, ‘NA’ AS DAY_OF_WEEK_SHORT_NAME
, ‘NA’ AS CAL_MONTH_FULL_NAME
, ‘NA’ AS CAL_MONTH_SHORT_NAME
, 0 AS CAL_MONTH_ENUM
, ‘NA’ AS CAL_QTR_NAME
, 0 AS CAL_QTR_ENUM
, ‘NA’ AS CAL_HYR_NAME
, 0 AS CAL_HYR_ENUM
, 9999 AS CAL_YEAR
, TO_DATE(’31-DEC-9999′, ‘DD-MON-YYYY’) AS START_OF_MONTH
, TO_DATE(’31-DEC-9999′, ‘DD-MON-YYYY’) AS END_OF_MONTH
FROM DUAL
)
AS CALENDAR_DATES
)
INTO CALENDAR_DATE
FROM DUAL;
RETURN CALENDAR_DATE;
END;

Below is as screenshot of the results of this SQL executed in Oracle’s fee online SQL learning and execution tool: Oracle Live SQL.

datedimensiondatagenerator

 

Advertisements

VLOOKUP: Right to Left Lookup

We all now know that VLOOKUP has one major constraint that the column in the lookup table from where the lookup value is to be searched should be the first column in the lookup table.

Here is a tricky way that you can use to overcome this constraint. The trick is, if we can build the table_array argument (i.e., the lookup table) of the function at runtime in a way ensuring that the first column is the column in the lookup table that is to be searched for the lookup value, the problem is resolved. This is achieved using CHOOSE function inside VLOOKUP in the place of table_array argument to build the lookup table in desired manner at runtime.

Example: Lets understand this with an example. Below are the customer names and their respective phone numbers. you are given a customer name and asked to lookup the customer name from this table and return the phone number of the respective customer.

Challenge: However, the customer name column in the lookup table from which the lookup value will be searched is not in the first position. see the screenshot below:

VLookup_3_1

Solution: Here is the VLOOKUP function with CHOOSE function in place of lookup table to return the right values entered in cell F36 to lookup the value in cell F35 and search it in the range B36:C36 (obviously not in the first column) and return the phone number. see the below screenshot:

=VLOOKUP(F35,CHOOSE({1,2}, C36:C46, B36:B46), 2,FALSE)

VLookup_3_2

Explanation:

First argument to the function:  WHAT to search/Lookup: cell F35 has the value to be looked up.

2nd argument to the function – WHERE to search/lookup: Here is the CHOOISE function is used as follows: CHOOSE({1,2}, C36:C46, B36:B46). Here the first argument {1,2} will arrange the arrays referred in 2nd and 3rd parameters in that order (i.e., the array referred in 3rd argument of CHOOSE function – C36:C46 comes first and then comes the array referred in 4th argument of CHOOSE function – B36:B46) and returns it as a range/lookup table. so when this happens, the returned lookup table will have C46:C36 as first column that has customer names where the lookup value from cell F35 will be searched, and B36:B46 as second column that has the phone number to be returned.

3rd argument to the function – WHICH column in the lookup table, returned at runtime, enumerating from left to write (corresponding to the row where the lookup value is found) has the value to be returned ? Here phone number to be returned is in column in the 2nd position (i.e., B36:B46) in the lookup table returned at runtime.

4th argument to the function – How to search. Here we only want to perform exact search. So, argument passed here is 0(zero) or FALSE.

Testing:

Now in the screenshot above, we already have a customer name in the cell F35 – “rathod”, so the value returned should be: 7174683825. When you hit enter “after” key after entering the formula in cell F36, you would see the correct value being returned as in the below screenshot.

VLookup_3_3

Hope you enjoyed reading this post..!!

Want to learn more VLOOKUP tricks..? Follow my blog by entering your email and then hitting on FOLLOW button at the top right. Happy Learning.. 🙂

Do leave your comments, if any..

Introduction to VLOOKUP in MS Excel

Hi friends… one of the important features of Excel which every user of Excel is expected to be aware of, is VLOOKUP function. Here I take you through the nuts and bolts of VLOOKUP:

What does VLOOKUP do ? VLOOKUP function looks up (searches)  a value in one column and then returns the corresponding value in the same row from another desired column.

It’s similar to searching for the phone number of a person from a phone directory where you would first search for the name of the person and then move across that row towards the phone number column and then take a note of the value found in that phone number column.

Signature of the function:                                                                                                

VLOOKUP(lookup_value, table_array, column_index_num, [table_range])

Explanation of arguments of the function:

lookup_value: This argument indicates WHAT is the value that you want to lookup or search.

table_array: This argument indicates WHERE do you want to lookup or search. This argument is also known as lookup table. The lookup value will be searched ONLY in the FIRST column of the lookup table.

column_index_num: This argument indicates value from WHICH column in the lookup table is to be returned.

table_range: This argument indicates whether the search process need to be exact type or approximate type. 0 (zero) or FALSE indicates exact match, 1 or TRUE indicates approximate match. This argument is optional. Although FALSE is most frequently used, TRUE is the default value for this argument, if nothing is specified.

An example is better than a precept.

So, lets understand the working of VLOOKUP function with a couple of examples using some fictitious data:

Example 1.

Scenario: Here are some customer names with their phone numbers alongside maintained by an analyst. The requirement is that the manager will determine the lucky customer each month by some lucky draw and ask for his/her phone number from the analyst, so that the customer may be contacted on Phone.

Now the analyst do not want to search for the customer in that long list of customer and phone numbers manually as we do in a phone directory. He just wanted to enter the name of the person in the cell beside “Best Employee” (i.e., in G2) so that the phone number of the customer is automatically displayed in the cell beside “Phone Number” (i.e., in G3), as in the below screenshot.

Now, lets write the VLOOKUP formula in cell G3 to return the Phone Number of the Lucky Customer  present in cell G2 by looking up or searching for that customer in the lookup table spread across the range – B3:C13.

=VLOOKUP(G2,B6:C16,2,FALSE)

VLookup_1_1

Explanation:

WHAT to search: cell G2 has the name of the customer that you want to search.

WHERE to search: the first column in the range B3:C13 is the place where the customer name is to be searched.

value of WHICH column of the range in the corresponding row to return: proceeding from left to right in the range and numbering the columns starting from number 1, in mind, Phone Number column gets number 2. since we want the value from Phone Number column to be returned finally, we specify its enumerator, i.e., 2 here.

Last argument indicating Match Type: Since, we want search for the exact name of the customer in cell G2 from the first column of the lookup table, we will indicate 0 or FALSE here.

Now when you press enter after entering the formula in cell G3, it initially returns a “#NA” since we haven’t yet entered any Lucky Customer name in cell G2.

Testing:

Now lets test our VLOOKUP formula by entering a name of a customer as Lucky Customer in cell G2 to see if it returns the correct phone number of that customer.

I entered “Rathod” as Luck Customer and it correctly returned the respective Phone Number as highlighted the record of this customer in the lookup table in yellow:

VLookup_1_2

* Remember that VLOOKUP does case insensitive search. Hence, in the above example, if you have entered “rathod” in the place of “Rathod”, you would still see the right value being returned.

Caveats: If the column in the lookup table where the lookup value to be searched is not the first column of the lookup table, VLOOKUP wouldn’t work.

Hope you enjoyed reading this post..!! Want to learn more variations of VLOOKUP addressing more challenging business data analysis problems …..? Follow my blog by just entering your email id and hit on follow button at the top right of this blog post..

Single T-SQL query to swapping the values of two columns without using temporary column

How to swap the values of two columns of a table ?

Let me explain the scenario with an example –

Let’s create a table named “Employees” with columns “First_Name” and “Last_Name”. Then populate the table with some fictitious data. Then view the results once and then interchange the values in the “First_Name” and “Last_Name” columns of the table. Then see the results in the table again to verify. The below T-SQL does all this:

Interchanging column values in a table
Interchanging column values in a table

Usually the UPDATE statement as in the above picture gives the impression of the both columns returning the same set of values (here Last_Name column values in both columns). But SQL Server behaves intelligent and interchanges the values in the two columns. It internally stores the values in a temporary column and then does the interchange.

Hope you enjoyed reading this post and found somewhat interesting learning. Keep coming back or follow this “Data Language” blog for more such interesting posts.

Happy time until my next blog post.. 🙂