For years my guys have been a proponent of ANSI compliant SQL. Today I decided to take the plunge and force myself to abandon the only SQL I have ever known and that was firmly grounded in an Oracle world (some might say grounded in cement shoes).
I made this decision not only because it is something that works across platforms but also as I been reminded over and over again by those I manage that at the end ANSI compliant SQL is simpler to understand and maintain.
To help others that might follow in my footsteps, I wanted to document my learning process by posting here. I thought I'd start with something very simple - illustrate how joins differ between a more traditional Oracle SQL query and a purely ANSI one.
Typical Inner Joins
Let's start with a very simple query that uses a traditional join. In a Oracle world, the syntax for this uses the WHERE clause to join the two tables.
Take the example below where I want to join an employee's profile record to the agency that he or she belongs. Both tables are referenced in my FROM clause and in my WHERE clause I include a hard join that allows me to bring back the name of the agency to which the employee belongs.
One might also consider the case where for some reason the agency referenced didn't exist or there wasn't an agency specified in the employee's profile record. In this case the query would not bring back a row. That can be solved with an outer join - but more in that in a minute.
Below is the query as I used to write it for Oracle:
select first_name
, last_name
, agency_name
from employee_profile ep
, agency a
where ep.agency_id = a.agency_id
select first_name
, last_name
, agency_name
from employee_profile ep
inner join agency a
on ep.agency_id = a.agency_id
In this particular case as illustrated above my WHERE clause disappears. That was one of the first things that jumped out at me as I could immediately see how my query is simplified.
Outer Joins
It is pretty safe to say that outer joins are an area where Oracle has their own "unusual" syntax that they introduced to handle this type of join. Oracle uses a plus sign surrounded by parenthesis (+) to indicate that side of the join is "optional" when attempting to link the two tables.
Let's build on the prior inner join example and if the selected employee's agency has been awarded a certification we want to be able to display the type of certificate. In a strictly Oracle world, I'd add the certificate table to my FROM clause and then add an outer join to my WHERE clause to indicate I want to pull back the certificate name only if there is a certification specified for the agency.
select first_name
, last_name
, agency_name
from employee_profile ep
, agency a
, certificate c
where ep.agency_id = a.agency_id
and a.certificate_id = c.certificate_id (+)
select first_name
, last_name
, agency_name
from employee_profile ep
inner join agency a
on ep.agency_id = a.agency_id
left outer join certificate c
on a.certificate_id = c.certificate_id
Looking at the SQL as written above it again is striking how simple the resultant query becomes. I still do not have a WHERE clause and have performed all of the appropriate joins in the FROM clause. The WHERE clause at this point strictly becomes a way to add additional filter criteria. That being said, one could also add additional filter criteria within the FROM clause when building your joins.
For example, let's say that we only want to show the certificate if it is one that is part of a federal compliance program. We would simply add that filter criteria to the outer join we have already provided. Any records matching the outer join on the certificate ID simply wouldn't be displayed unless they are marked for federal compliance (i.e., and c.federal_compliance = 'Y').
select first_name
, last_name
, agency_name
from employee_profile ep
inner join agency a
on ep.agency_id = a.agency_id
left outer join certificate c
on a.certificate_id = c.certificate_id
and c.federal_compliance = 'Y'
Reviewing the resulting SQL it is again easy to see how simplified the query becomes when you make it ANSI compliant. I still do not have a WHERE clause having performed all of the appropriate joining in the FROM clause to include my additional filter criteria with ensuring the certificate is part of a federal compliance program.
Cartesian Joins
I almost didn't include this example but it also illustrates a simplification. Let's say I have two tables - one that tracks day in year (e.g., 1 - 365) and a table to track hours (i.e., 1-24). If I want to combine these two tables to fall all permutations, previously I would have written a query as follows:
select day_id, hour_id
from days, hours
from days, hours
Now that query becomes:
select day_id, hour_id
from days
cross join hours
from days
cross join hours
Although not much simpler to write it does read in a much more straightforward fashion. In general that probably is the most significant thing I learned when converting over to using ANSI compliant SQL - that what you produce is much easier for others to read. This is especially more true as the size of your query grows and the number of joins you are specifying becomes larger and larger.
So that is it for the time being.