Thursday, December 8, 2016

SQL query puzzle - List country and languages spoken

Given a table of country and language spoken,  fetch country and comma separated languages spoken list using a SQL query.
Given table example entries:
Country Language
India Hindi
India Kannada
India Tamil
China Mandarine
China Cantonese
 
Expected Result of SQL Query:
Country Language_list
India Hindi, Kannada, Tamil
China Madarine, Cantonese
 
constraint: no further querying is allowed from supporting objects of SQL query in question. 

SELECT COUNTRY, LISTAGG(LANGUAGE, ', ') WITHIN GROUP (ORDER BY LANGUAGE) LANGUAGE_LIST FROM COUNTRY_LANGUAGE_TABLE GROUP BY COUNTRY;
 

Move Oracle 11g XE(http server) from 8080 to 9090

Follow the below steps to change the port:
1. Click on "Run SQL Command Line"
2. connect system@xe
enter password
3.
SQL> begin
 2    dbms_xdb.sethttpport('9090');
 3  end;
 4  /

If you want to see the port after change use the following command:
SQL> select dbms_xdb.gethttpport from dual;

SQL - remove duplicates in LISTAGG result

Today I would like to share a common issue of removing duplicates in comma separated ordered list (example by LISTAGG) using SQL regular expressions
Syntax of REGEXP_REPLACE:
REGEXP_REPLACE(src, regExMatch, regExReplace) :-
This function does following till end of src string
1. Find matching string in src as per given 'regExMatch'
2. Replace matching string in step 1,  with replace string, 'regExReplace'

Solution: REGEXP_REPLACE(ordered List, '([^,]*)(,\1)+($|,)'   ,'\1\3')
Important point Idea: Source string or list must be ordered for this solution.
Understanding the solution with example:
select
REGEXP_REPLACE( 'English,English,English,Hindi,Hindi,Kannada,Kannada,Kannada,Tamil,Tamil,Telugu,Telugu','([^,]*)(,\1)+($|,)'   ,'\1\3')
from dual
1. Understanding regExMatch expression: '([^,]*)(,\1)+($|,)'
There are three groups in above expression
group 1: ([^,]*) : match all or no characters till comma   
match Result: English
group 2: (,\1)+ : \1 - stands for first group which is Kannada, so it becomes (,English)+, meaning match one or more occurrences of  ',English'.
match Result: ,English,English
group 3: ($|,) : $ stands for 'end of string', | stands or. So it says match either end of string or a comma
match Result: ,    (this is comma which is following group2 match: ,English,English)
2. Understanding regExReplace expression '\1\3':
\1\3 represent the group number which are used in regExMatch expression.
replace Result: English,
Reference:
SELECT OBJID, MERKMAL,
           REGEXP_REPLACE(
                  LISTAGG(ddv.VALUE, ',') WITHIN GROUP (ORDER BY ddv.VALUE)
                  ,'([^,]*)(,\1)+($|,)'
                  ,'\1\3')

                   VALUE
FROM TT_V_RSOBJ_DOKUMENTE_DETAIL ddv
WHERE SCHEMA='RSOBJ_DOKUMENTE'
and MERKMAL in ('LAENDERAUSWAHL','SPRACHAUSWAHL','RESTRICTION','PROCESSING')
GROUP BY OBJID, MERKMAL;