I don't know if you will find this more "elegant", but here is a better way to write the query:
SELECT months.month_string, MAX(import.process_date)
FROM (select '01' as month_string from dual union all
select '02' as month_string from dual union all
select '03' as month_string from dual union all
select '04' as month_string from dual union all
select '05' as month_string from dual union all
select '06' as month_string from dual union all
select '07' as month_string from dual union all
select '08' as month_string from dual union all
select '09' as month_string from dual union all
select '10' as month_string from dual union all
select '11' as month_string from dual union all
select '12' as month_string from dual
) months LEFT OUTER JOIN
import
on import.process_month = months.month_string
GROUP BY months.month_string
ORDER BY months.month_string;
Here are the changes:
- Replaced the (uninterpretable) Oracle syntax for outer joins with an explicit, ANSI standard outer join.
- Reversed the order of the tables, to use a
left outer join
rather than aright outer join
. - Changed
select distinct
toselect
.select distinct
is almost never needed withgroup by
. - Changed
union
tounion all
.union
expends effort to remove duplicates, which is not needed. - Added
as
for the column aliases. This makes it more apparent that the name is being assigned to the column, and helps prevent wandering commas from messing up the query.
You could also use a connect by
or recursive CTE to actually generate the month numbers, but I'm not sure that would be as clear as this version.
EDIT:
I was making the assumption that you need to get NULL
values out because not all months would be present in import
. That is why you would use a months
table. If not, just do:
SELECT i.process_month, MAX(i.process_date)
FROM import i
GROUP BY i.process_month
ORDER BY i.process_month;
If you are concerned about the range,
SELECT i.process_month, MAX(i.process_date)
FROM import i
WHERE i.process_month in ('01', '02', '03', '04', '05', '06', '07', '08', '09', '10',
'11', '12'
)
GROUP BY i.process_month
ORDER BY i.process_month;