19c LISTAGG Can Do Distinct

19c LISTAGG Can Do Distinct

October 15, 2020 Off By dianarobete

Do you use analytic functions in Oracle? I do not use them as much as I’d like to, but I love analytic functions, as they really transform the queries, the resulting reports and most of all they make our life easier!
My favorite analytic function is LISTAGG.
I few years ago, I wrote a blog post about LISTAGG, as it helped me a lot in scripting to check some privileges. You can check that out here: How To Use LISTAGG To Create Awesome DBA Reports.

In 19c, Oracle introduced the distinct feature for the LISTAGG function, eliminating duplicate values from the resulting string. Why is this a good thing? Because it removes the need to write complex queries, to try and accomplish the same results.

The LISTAGG function is aggregating a list of results for a column, in a specified sequence within a group. For example I want to list the privileges assigned to a role in the following format. For this exercise, I only want to see the high level permissions, I am not interested in the object level privileges that are granted.

ROLE_NAME		       PRIVILEGES
------------------------------ ----------------------------------
APPS_ADMIN		       DELETE,INSERT,SELECT,UPDATE

Let’s say this role has the following grants:

select table_name, privilege 
from dba_tab_privs
where grantee='APPS_ADMIN';

TABLE_NAME	PRIVILEGE
--------------	-----------
TEST_TBL1	SELECT
TEST_TBL1	UPDATE
TEST_TBL1	DELETE
TEST_TBL2	SELECT
TEST_TBL2	INSERT

If I were to list the privileges with the LISTAGG, prior to 19c, the results would look like this:

select grantee as role_name, listagg(privilege,',') 
       within group (order by privilege) as privileges
from dba_tab_privs
where grantee='APPS_ADMIN'
group by grantee;

ROLE_NAME		       PRIVILEGES
------------------------------ ----------------------------------
APPS_ADMIN		       DELETE,INSERT,SELECT,SELECT,UPDATE

Do you notice the duplicate entry for the select statement? I kind of want to eliminate that duplication. Prior to 19c you would have had to write complex queries to eliminate these duplicates.
In 19c this is much easier to do:

select grantee as role_name, listagg(distinct privilege,',') within group (order by privilege) as privileges
from dba_tab_privs
where grantee='APPS_ADMIN'
group by grantee;

ROLE_NAME		       PRIVILEGES
------------------------------ ----------------------------------
APPS_ADMIN		       DELETE,INSERT,SELECT,UPDATE

Do you use LISTAGG a lot? What analytic functions do you like to use?

Leave a comment below and let me know! I read every comment!

If you enjoyed this article, and would like to learn more about databases, please sign up to my weekly email, and you will receive my FREE guide: 7 Questions to Ask When Troubleshooting Database Performance Problems!


If you are interested in improving your Oracle Tuning skills, check out my course theultimatesqltuningformula.comFollow the link to get the best price, only $18.99 CAD!