String concatenation for a matrix of two tables

I have 3 tables in my PostgreSQL database, realizing the relationship "many-to-many": droit, roleand role_droit. See the chart in the attached image. I have this query to return the current result (also in the image):

SELECT matrix_view.droit_id,
    sum(case when matrix_view.aid = 1 then haspair end) as  "role A" ,
    sum(case when matrix_view.aid = 2 then haspair end) as  "role B" ,
    sum(case when matrix_view.aid = 3 then haspair end) as  "role C" ,
    sum(case when matrix_view.aid = 4 then haspair end) as  "role D"
from (
        SELECT allRD.aid as aid, allRD.droit_id, max(case when RD.role_id is not null then 1 else 0 end) as HasPair
        from (
                select distinct a.role_id as aid, b.droit_id as droit_id
                from role a cross join droit b 
             ) as allRD 
        left outer join role_Droit RD
        on allRD.aid = RD.role_id and allRD.droit_id = RD.droit_id
        group by  allRD.droit_id,  allRD.aid
        order by  allRD.aid
    ) AS matrix_view
group by matrix_view.droit_id
order by matrix_view.droit_id

I would like to show concatenation id_droit, id_roleand haspairat the intersection between droitand role! the desired result is also on the image:

Examples of data and results

+4
source share
2 answers

Typically, the problem is with the center or crosstab. But since you need results for a small given set of roles, we can use the shortcut:

SELECT droit_name
     , droit_id || ',1,' || EXISTS (SELECT FROM role_droit WHERE droit_id = d.droit_id AND role_id = 1)::int AS "role A"
     , droit_id || ',2,' || EXISTS (SELECT FROM role_droit WHERE droit_id = d.droit_id AND role_id = 2)::int AS "role B"
     , droit_id || ',3,' || EXISTS (SELECT FROM role_droit WHERE droit_id = d.droit_id AND role_id = 3)::int AS "role C"
     , droit_id || ',4,' || EXISTS (SELECT FROM role_droit WHERE droit_id = d.droit_id AND role_id = 4)::int AS "role D"
FROM   droit d
ORDER  BY droit_id;

.

, , SQL .

dbfiddle

0

, : ("role A" , "role B" , "role C" , "role D"), .

:

SELECT cast(matrix_view.droit_name as text),
    matrix_view.droit_id || ',' || sum(case when matrix_view.aid = 1 then matrix_view.aid end) || ',' || sum(case when matrix_view.aid = 1 then haspair end) as  "role A" ,
    matrix_view.droit_id || ',' || sum(case when matrix_view.aid = 2 then matrix_view.aid end) || ',' || sum(case when matrix_view.aid = 2 then haspair end) as  "role B" ,
    matrix_view.droit_id || ',' || sum(case when matrix_view.aid = 3 then matrix_view.aid end) || ',' || sum(case when matrix_view.aid = 3 then haspair end) as  "role C" ,
    matrix_view.droit_id || ',' || sum(case when matrix_view.aid = 4 then matrix_view.aid end) || ',' || sum(case when matrix_view.aid = 4 then haspair end) as  "role D"

from (
        SELECT allRD.aid as aid, allRD.droit_id,allRD.droit_name , max(case when RD.role_id is not null then 1 else 0 end) as HasPair
        from (
                select distinct a.role_id as aid, b.droit_id as droit_id , b.droit_name as droit_name
                from role a cross join droit b 
             ) as allRD 
        left outer join role_Droit RD
        on allRD.aid = RD.role_id and allRD.droit_id = RD.droit_id
        group by  allRD.droit_id,  allRD.aid ,allRD.droit_name
        order by  allRD.aid
    ) AS matrix_view
group by matrix_view.droit_id, matrix_view.droit_name
order by matrix_view.droit_id
0

Source: https://habr.com/ru/post/1692551/


All Articles