1

I have 3 tables which i want to join and i just need the data for 1 staff in 1 row but i get multiple or more to say multiplied rows.

staff:

uid surname
1234 Miller
4567 Jake

position:

uid role from to
1234 Engineer jan dec
1234 Worker jan dec

knowledge:

uid certificate from to
1234 cert1 jan dec
1234 cert2 jan feb

position content has no relation/dependency to knowledge content.

This is what i get with my sql query, obviously without the header as i dont know to do this but just here for understanding with header. I get 4 (2x2) lines but as mentioned before i don't need this as data is completely unrelated from the two tables position and knowledge

uid surname role from to certificate from to
1234 Miller Engineer jan dec cert1 jan dec
1234 Miller Engineer jan dec cert2 jan feb
1234 Miller Worker jan dec cert1 jan dec
1234 Miller Worker jan de cert2 jan feb

This what i tried:

Select st.uid, st.surname, pos.role, pos.from, pos.to, knw.certificate, knw.from, knw.to 
from staff st 
join position pos on st.uid=pos=uid 
join knowledge knw on st.uid=knw.uid 
WHERE st.uid='1234'

What i'm trying to get:

uid surname role from to role from to certificate from to certificate from to
1234 Miller Engineer jan dec Worker jan dec cert1 jan dec cert2 jan feb

Roles and also certificates can be none or even more and should be lined up in one row. I used google to find solutions to show in one row but just got the typical "just show 1 row of table" (TOP) as search results. I don't need the header and would be interested in a data result only to have a better understanding and not to overcomplicate stuff. Thank you.

nbk
  • 45,398
  • 8
  • 30
  • 47
  • which database are you using, and look form pivot or if there are more roles, you use the term dynamic pivot – nbk Nov 17 '22 at 12:47
  • why choose Engineer rather than Worker? what is the criteria? – jose_bacoy Nov 17 '22 at 12:49
  • @nbk Oracle ... – Sailor Moon Nov 17 '22 at 12:51
  • 1
    @jose_bacoy i dont know what you mean honestly, its just an example but users can have multiple roles at the same time – Sailor Moon Nov 17 '22 at 12:59
  • Does this answer your question? [Dynamic Pivot in Oracle's SQL](https://stackoverflow.com/questions/15491661/dynamic-pivot-in-oracles-sql) – astentx Nov 17 '22 at 13:30
  • You actually have two sets of data to PIVOT – position and knowledge. Do you want your query to return the same number of columns across all staff or do you need the number of columns to dynamically adjust to be the minimum number needed to return the data? – Jason Seek Well Nov 17 '22 at 16:44

1 Answers1

0

Well, you could get a very wide row as a result. You can get that row with all combinations covered but there is a question of how useful it could be. Anyway, with your sample data:

WITH
    staff AS
        (
        Select 1234 "ID", 'Miller' "SURNAME" From Dual Union All
        Select 4567 "UID", 'Jake'   "SURNAME" From Dual 
        ),
    position AS
        (
        Select 1234 "ID", 'Engineer' "POS_ROLE", 'JAN' "POS_FROM", 'DEC' "POS_TO" From Dual Union All
        Select 1234 "ID", 'Worker'   "POS_ROLE", 'JAN' "POS_FROM", 'DEC' "POS_TO" From Dual  
        ),
    knowledge AS
        (
        Select 1234 "ID", 'Cert 1' "CERT", 'JAN' "CERT_FROM", 'DEC' "CERT_TO" From Dual Union All
        Select 1234 "ID", 'Cert 2' "CERT", 'JAN' "CERT_FROM", 'FEB' "CERT_TO" From Dual  
        )

SQL getting the full row (with all combinations covered):

SELECT 
    ID, SURNAME "Surname", 
    A_ROLE "Role", A_P_FROM "From", A_P_TO "To", 
    B_ROLE "Role", B_P_FROM "From", B_P_TO "To",
    C_ROLE "Role", C_P_FROM "From", C_P_TO "To",
    D_ROLE "Role", D_P_FROM "From", D_P_TO "To",
    --
    A_CERT "Cert", A_C_FROM "From", A_C_TO "To", 
    B_CERT "Cert", B_C_FROM "From", B_C_TO "To", 
    C_CERT "Cert", C_C_FROM "From", C_C_TO "To", 
    D_CERT "Cert", D_C_FROM "From", D_C_TO "To"
FROM
    (
        Select DISTINCT
            ROWNUM "IDX",
            s.ID, s.SURNAME "SURNAME",
            p.POS_ROLE "POS", k.CERT "CERT",
            p.POS_FROM "P_FROM", p.POS_TO "P_TO",
            k.CERT_FROM "C_FROM", k.CERT_TO "C_TO"
        From
            staff s
        Inner Join
            position p ON (p.ID = s.ID)
        Inner Join
            knowledge k ON (k.ID = s.ID)
        Where s.ID = 1234
        Order By s.ID, p.POS_ROLE, k.CERT
    ) 
    PIVOT (
              Max(POS) "ROLE", Max(P_FROM) "P_FROM", Max(P_TO) "P_TO",
              Max(CERT) "CERT", Max(C_FROM) "C_FROM", Max(C_TO) "C_TO"
              FOR (IDX) IN(1 "A", 2 "B", 3 "C", 4 "D")
          )
/*    R e s u l t :
        ID Surname Role     From To  Role     From To  Role     From To  Role     From To  Cert   From To  Cert   From To  Cert   From To  Cert   From To
---------- ------- -------- ---- --- -------- ---- --- -------- ---- --- -------- ---- --- ------ ---- --- ------ ---- --- ------ ---- --- ------ ---- ---
      1234 Miller  Worker   JAN  DEC Engineer JAN  DEC Worker   JAN  DEC Engineer JAN  DEC Cert 1 JAN  DEC Cert 1 JAN  DEC Cert 2 JAN  FEB Cert 2 JAN  FEB
*/

There is a lot of repeating values because the sample data is repeatig too. In the innermost query there is ROWNUM pseudo column used in Pivot's FOR list of values and aliases. It could be even widened if needed.
Because of different levels of pivoting (ordering also could affect this) and that repeating data for your exact expecting result your selection list in outermost SQL should take A and B ROLES, plus A and C CERTS.

SELECT 
    ID, SURNAME "Surname", 
    A_ROLE "Role", A_P_FROM "From", A_P_TO "To", 
    B_ROLE "Role", B_P_FROM "From", B_P_TO "To",
  --
    A_CERT "Cert", A_C_FROM "From", A_C_TO "To", 
    C_CERT "Cert", C_C_FROM "From", C_C_TO "To"
FROM
...

/*   R e s u l t :
ID         Surname Role     From To  Role     From To  Cert   From To  Cert   From To
---------- ------- -------- ---- --- -------- ---- --- ------ ---- --- ------ ---- ---
      1234 Miller  Worker   JAN  DEC Engineer JAN  DEC Cert 1 JAN  DEC Cert 2 JAN  FEB
*/

This is caused by ROWNUM and ordering - one of the columns would always be infront of another either you sort it by role, cert or cert, role...
There is a lot of questions unanswerd that could pop up like processing IDs separately not to confuze the Pivot's Max() function... Anyway, you could try to adjust it to your actual data.
Regards...

d r
  • 3,848
  • 2
  • 4
  • 15