I’m stuck on a SQL while working on an audit report.
We have reports that draw data from multiple universes. In the AUDIT_DETAIL table I see multiple rows for a single EVENT_ID where DETAIL_TYPE_ID = 2. And that part is just fine, it’s expected.
But when it comes to querying that I run into a spot of bother that I’d love an extra pair of eyes to look at please.
SELECT event_id
,DBMS_LOB.SUBSTR( Detail_Text, 100, 1 ) AS name_name
,ROW_NUMBER( ) OVER (PARTITION BY event_id ORDER BY DBMS_LOB.SUBSTR( Detail_Text, 100, 1 )) AS rnum
FROM php_boe_audit.AUDIT_DETAIL
WHERE detail_type_id = 2 AND event_id = 10401996175157592097
The event_id filter on this is simply to reduce the results to a bite sized chunk for development. In real life I’ll be using an event data filter to collect only “new” events.
This SQL gives me two rows back (bite sized, see?)
event_id name_name rnum
10401996175157592097 Universe One 1
10401996175157592097 Universe Two 2
Now, for my output, I want the two universes to be listed as a single row, not two. Also, while this example has two universes, others have more, so my SQL solution has to be generic.
WITH got_rnum
AS (SELECT '10401996175157592097' AS event_id, 'Universe One' AS name_name, 1 AS rnum FROM DUAL
UNION ALL
SELECT '10401996175157592097', 'Universe Two', 2 FROM DUAL)
SELECT event_id, LTRIM( SYS_CONNECT_BY_PATH( name_name, ', ' ), ', ' ) AS universe_list
FROM got_rnum
WHERE CONNECT_BY_ISLEAF = 1
START WITH rnum = 1
CONNECT BY event_id = PRIOR event_id AND rnum = PRIOR rnum + 1;
This SQL substitutes the output of the first as the sub query (I’m working up to the part that makes me scratch my head) and the results are exactly what I want to see.
event_id universe_list
10401996175157592097 Universe One, Universe Two
If instead of dropping the hard coded results of the first SQL into the second, I drop in the SELECT statement itself.
WITH got_rnum
AS (SELECT event_id
,DBMS_LOB.SUBSTR( Detail_Text, 100, 1 ) AS name_name
,ROW_NUMBER( ) OVER (PARTITION BY event_id ORDER BY DBMS_LOB.SUBSTR( Detail_Text, 100, 1 )) AS rnum
FROM php_boe_audit.AUDIT_DETAIL
WHERE detail_type_id = 2 AND event_id = 10401996175157592097)
SELECT event_id, LTRIM( SYS_CONNECT_BY_PATH( name_name, ', ' ), ', ' ) AS universe_list
FROM got_rnum
WHERE CONNECT_BY_ISLEAF = 1
START WITH rnum = 1
CONNECT BY event_id = PRIOR event_id AND rnum = (PRIOR rnum) + 1;
I get the following output
event_id universe_list
10401996175157592097 Universe One
This is neither what I expected, nor what I wanted. But I suspect somehow it’s exactly what I asked for. Can a fresh pair of eyes see what I’m doing wrong and help me write the SQL in a way that it gives me what I want?
Please and thank you!
EDIT:
I even tried a rewrite of the final SQL and all it did was take longer to run (13 minutes instead of 3 minutes)
SELECT event_id, LTRIM( SYS_CONNECT_BY_PATH( name_name, ', ' ), ', ' ) AS universe_list
FROM (SELECT event_id
,DBMS_LOB.SUBSTR( Detail_Text, 100, 1 ) AS name_name
,ROW_NUMBER( ) OVER (PARTITION BY event_id ORDER BY DBMS_LOB.SUBSTR( Detail_Text, 100, 1 )) AS rnum
FROM php_boe_audit.AUDIT_DETAIL
WHERE detail_type_id = 2 AND event_id = 10401996175157592097)
WHERE CONNECT_BY_ISLEAF = 1
START WITH rnum = 1
CONNECT BY event_id = PRIOR event_id AND rnum = ( PRIOR rnum ) + 1;
Giving me the same undesirable output.
kbrazell (BOB member since 2003-08-19)