0

Currently I have written:

SELECT IT_ID, SUBSTR (SYS_CONNECT_BY_PATH (grp , ','), 2) GROUPS
FROM (SELECT U.IT_ID, LAST_NAME, FIRST_NAME, GRP, ROW_NUMBER() OVER (ORDER BY U.IT_ID) rn, COUNT(*) OVER() cnt
FROM ECG_IT_USERS U
JOIN SECUREGROUPS G ON U.IT_ID = G.IT_ID)

START WITH rn = 1
CONNECT BY rn = PRIOR rn + 1

This returns:

IT_ID   GROUPS

afz23   ADMIN
afz23   ADMIN,QA
alv77   ADMIN,QA,USER
jaj23   ADMIN,QA,USER,USER
klo26   ADMIN,QA,USER,USER,PROD
klo26   ADMIN,QA,USER,USER,PROD,ADMIN
klo26   ADMIN,QA,USER,USER,PROD,ADMIN,QA
mav45   ADMIN,QA,USER,USER,PROD,ADMIN,QA,ADMIN

I can't figure out how I can make it reset after a new user is encountered? It seems to be carrying over the previous groups, even if the user does not belong to them.

I need to see:

IT_ID   GROUPS

afz23   ADMIN,QA
alv77   USER
jaj23   USER
klo26   PROD,ADMIN,QA
mav45   ADMIN
antonpug
  • 13,724
  • 28
  • 88
  • 129
  • possible duplicate of [Is there an Oracle SQL query that aggregates multiple rows into one row?](http://stackoverflow.com/questions/1120706/is-there-an-oracle-sql-query-that-aggregates-multiple-rows-into-one-row) – a'r Nov 04 '11 at 16:42
  • I don't have the relevant functions in my version of DB2, but what happens if you add `AND it_id = PRIOR it_id` to the `CONNECT BY` clause (and is it even possible)? – Clockwork-Muse Nov 04 '11 at 21:18

1 Answers1

0

There are three things you need to do here.

Firstly you need to add a partition to the row_number function so that it starts the numbering from 1 for each IT_ID. You also need to add the IT_ID column to the connect by so that it only takes rows with the same IT_ID value. Finally you need to group by the it_id column to remove the duplicate rows.

The final query would be

with ECG_IT_USERS as (
  select 'afz23' as it_id from dual union all
  select 'alv77' as it_id from dual union all
  select 'jaj23' as it_id from dual union all
  select 'klo26' as it_id from dual union all
  select 'mav45' as it_id from dual
),
securegroups as (
  select 'afz23' as it_id, 'ADMIN' as grp from dual union all
  select 'afz23' as it_id, 'QA' as grp from dual union all
  select 'alv77' as it_id, 'USER' as grp from dual union all
  select 'jaj23' as it_id, 'USER' as grp from dual union all
  select 'klo26' as it_id, 'PROD' as grp from dual union all
  select 'klo26' as it_id, 'ADMIN' as grp from dual union all
  select 'klo26' as it_id, 'QA' as grp from dual union all
  select 'mav45' as it_id, 'ADMIN' as grp from dual
)
SELECT 
  IT_ID, 
  Max(SUBSTR (SYS_CONNECT_BY_PATH (grp , ','), 2)) GROUPS
FROM (
  SELECT 
    U.IT_ID, 
--    LAST_NAME, 
--    BFIRST_NAME, 
    GRP, 
    ROW_NUMBER() OVER (partition by u.it_id ORDER BY U.IT_ID) rn, 
    COUNT(*) OVER() cnt
FROM ECG_IT_USERS U
JOIN SECUREGROUPS G ON (U.IT_ID = G.IT_ID))
START WITH rn = 1
CONNECT BY rn = PRIOR rn + 1 and it_id = prior it_id
Group by it_id

This produces the following output for me:

IT_ID GROUPS
----- --------------------
alv77 USER
afz23 ADMIN,QA
jaj23 USER
mav45 ADMIN
klo26 PROD,ADMIN,QA

EDIT: I have added a with clause with some sample data and this runs for me without any problems although I did comment out the last_name and first_name columns since they don't have an effect on the final query and I put some brackets around the join condition.

Maybe it would pay to start with the query I've got above, check that it works for you initially and modify it as appropriate.

Mike Meyers
  • 2,885
  • 1
  • 20
  • 26
  • Thanks! I am having an issue though, the START/CONNECT BY clauses do not recognize rn, says Invalid Identifier? I am guessing because it is invisible to external calls? But it is strange – antonpug Nov 07 '11 at 13:51
  • @antonpug: I've added some sample data to the query so see if that works for you now. – Mike Meyers Nov 08 '11 at 14:57