简体   繁体   中英

listagg function is failing

I am trying to use listagg as listagg(select...) way but I guess that it is not possible in the way I would like to say.

I have a table of degrees.

Degree table:
-----------------------------------------------
| user_id | degree_fi | degree_en | degree_sv |
-----------------------------------------------
| 3601464 | 3700      |  1600     |  2200     |
|  1020   | 100       |  0        |   0       |
| 3600520 |  100      | 1300      |  1400     |
| 3600882 |  0        |   100     |  200      |
| 3600520 |  3200     |   800     |  600      |
| 3600520 |  400      | 3000      |  1500     |
-----------------------------------------------

Then I have another table with the names of those degress.

codes:
------------------------------
|  degree_code |  degree_text|
------------------------------
|   3700       |  Masters    |
|   100        | Bachelors   |
|   3200       | Doctorate   |
|   400        |  Diploma A  |
|   1600       | High school |
|   1300       | Secondary   |
|   800        | Post doc    |
|   3000       | Training    |
|   2200       | LLB         |
|   1400       | M.Sc        |
|   200        |  B.Sc       |
|   600        | Foreign Dip |
|   1500       | Failure     |
------------------------------

What I would like to have is something like this:

--------------------------------------------------------------------------------------------------------------------------------------------------------------
 | user_id | degree_fi    | degree_fi_txt                   | degree_en       | degree_en_txt                  |degree_sv        | degree_sv_txt              |
 --------------------------------------------------------------------------------------------------------------------------------------------------------------
 | 3601464 | 3700         | Masters                         | 1600            |  high school                   |  2200           |   LLB                      |
 |  1020   | 100          | Bachelors                       | 0               |                                |   0             |                            |
 | 3600520 | 100,3200,400 | Bachelors, Doctorate, Diploma A | 1300, 800, 3000 |  secondary, post doc, Training | 1400, 600, 1500 | M.Sc, Foreign Dip, Failure | 
 | 3600882 |  0           |                                 | 100             |  Bachelors                     |  200            |   B.Sc                     |
  -------------------------------------------------------------------------------------------------------------------------------------------------------------

I have tried to use listagg function like this:

SELECT user_id, listagg(degree_fi, ',') within GROUP (ORDER BY degree_fi) degree_fi,
                listagg(SELECT degree_text from codes WHERE degree_code IN (SELECT degree_fi feom degree), ',') within GROUP (ORDER BY degree_text) degree_fi_txt,
                listagg(degree_en, ',') within GROUP (ORDER BY degree_en) degree_en,
                listagg(SELECT degree_text from codes WHERE degree_code IN (SELECT degree_en feom degree), ',') within GROUP (ORDER BY degree_text) degree_en_txt,
                listagg(degree_sv, ',') within GROUP (ORDER BY degree_en) degree_sv
                listagg(SELECT degree_text from codes WHERE degree_code IN (SELECT degree_sv feom degree), ',') within GROUP (ORDER BY degree_text) degree_sv_txt,
FROM  degree GROUP BY user_id

But I am hitting the wall with it. Any recommendation?

Thanks in advance.

You just need to join to the codes table three times, instead of using the select inside the listagg :

SELECT user_id,
    listagg(d.degree_fi, ',')
        WITHIN GROUP (ORDER BY d.degree_fi) degree_fi,
    listagg(cf.degree_text, ',')
        WITHIN GROUP (ORDER BY d.degree_fi) degree_fi_txt,
    listagg(d.degree_en, ',')
        WITHIN GROUP (ORDER BY d.degree_en) degree_en,
    listagg(ce.degree_text, ',')
        WITHIN GROUP (ORDER BY d.degree_en) degree_en_txt,
    listagg(d.degree_sv, ',')
        WITHIN GROUP (ORDER BY d.degree_sv) degree_sv,
    listagg(cs.degree_text, ',')
        WITHIN GROUP (ORDER BY d.degree_sv) degree_sv_txt
FROM degree d
LEFT JOIN codes cf on cf.degree_code = d.degree_fi
LEFT JOIN codes ce on ce.degree_code = d.degree_en
LEFT JOIN codes cs on cs.degree_code = d.degree_sv
GROUP BY d.user_id
ORDER BY d.user_id;


   USER_ID DEGREE_FI            DEGREE_FI_TXT                  DEGREE_EN            DEGREE_EN_TXT                  DEGREE_SV            DEGREE_SV_TXT
---------- -------------------- ------------------------------ -------------------- ------------------------------ -------------------- ------------------------------
      1020 100                  Bachelors                      0                                                   0
   3600520 100,400,3200         Bachelors,Diploma A,Doctorate  800,1300,3000        Post doc,Secondary,Training    600,1400,1500        Foreign Dip,M.Sc,Failure
   3600882 0                                                   100                  Bachelors                      200                  B.Sc
   3601464 3700                 Masters                        1600                 High school                    2200                 LLB

I'm not sure if you wanted the degree_text values sorted alphabetically, or matching the order of the IDs; I've gone with the latter, but if you want the former you can just change the order by to cf.degree_text etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM