SQL

Using WITH to avoid duplicate code


Problem

Avoid duplicate code generated by a subquery

Assume you have a query where you have a subquery which you need multiple times. Once to check if something exists and once to output some data or build a total.

Such a query could look like this:

SELECT person, money FROM my_table
UNION ALL
SELECT 'TOTAL', SUM(money) FROM my_table

This would build a table where the last row shows you the total money you've got. In this situation, it's not much of a problem but imagine what happens if we have a more complicated query instead of "my_table". Not complicated but slightly more code:

SELECT person, money FROM my_table WHERE YEAR=2012 AND MONTH=1
UNION ALL
SELECT 'TOTAL', SUM(money) FROM my_table WHERE YEAR=2012 AND MONTH=1

Here you can easily see, that the WHERE conditions appear twice in our query. If it get more complicated, it could even happen, that you forget to modify one and produce an inconsitent result.


Solution

Recipe #1 - Using with to remove duplicate code

For this and much more, you can use with WITH clause. It's basically a tool you use, to materialize a subquery and avoid that Oracle has to execute them multiple times. Let's look at a simple example.

WITH subquery AS
  (
     SELECT 'remo' person, 100 money FROM DUAL
     UNION ALL
     SELECT 'rest',        12        FROM DUAL
  )
SELECT person, money FROM subquery

This query isn't really useful, it basically builds a virtually materialized subquery based on two SELECT .. FROM DUAL commands and shows the output of it. But what if we want to display another row at the end showing the total sum of money we've got? This is where the WITH clause gets handy:

WITH subquery AS
  (
     SELECT 'remo' person, 100 money FROM DUAL
     UNION ALL
     SELECT 'rest',        12        FROM DUAL
  )
SELECT person, money FROM subquery
UNION ALL
SELECT 'TOTAL', SUM(money) FROM subquery

This will print a table like this:

Person Money
remo 100
rest 12
TOTAL 112

Comments




Please sign-in to post a comment