Postgres选择从一个到多个表到单个表行

时间:2017-05-11 07:36:32

标签: sql postgresql

我有以下表格:

kid
  id
  name

kid_workshop
  id
  kid_id
  workshop_name

workshop_name可能只是: arts,martial_arts,chess,soccer

为了提高性能,我想创建一个如下所示的物化视图:

kid_id   name   arts   martial_arts   chess   soccer
  1      Dann   True   True           False   True

我该怎么办?我正在使用postgres

3 个答案:

答案 0 :(得分:1)

像往常一样:

create materialized view mv1 as 
select 
  k.id kidid
, name
, case when workshop_name = 'arts' then true else false end arts
, case when workshop_name = 'martial_arts' then true else false end martial_arts   
, case when workshop_name = 'chess' then true else false end chess
, case when workshop_name = 'soccer' then true else false end soccer
from kid k
join kid_workshop w on w.kid_id = k.id

答案 1 :(得分:1)

尝试:

select
  k.id kid_id,
  k.name,
  a.id is not null as arts,
  m.id is not null as martial_arts,
  c.id is not null as chess,
  s.id is not null as soccer
from kid k 
     outer join  kid_workshop a on a.kid_id = k.id and a.workshop_name = 'arts'
     outer join  kid_workshop m on m.kid_id = k.id and m.workshop_name = 'martial arts'
     outer join  kid_workshop c on c.kid_id = k.id and c.workshop_name = 'chess'
     outer join  kid_workshop s on s.kid_id = k.id and s.workshop_name = 'soccer'

答案 2 :(得分:1)

尝试以下查询:

create materialized view your_view as 
select
    k.id,
    k.name,
    max(case when kw.workshop_name = 'arts'
             then 'true' else 'false' end) arts,
    max(case when kw.workshop_name = 'martial_arts'
             then 'true' else 'false' end) martial_arts,
    max(case when kw.workshop_name = 'chess'
             then 'true' else 'false' end) chess,
    max(case when kw.workshop_name = 'soccer'
             then 'true' else 'false' end) soccer
from kid k
inner join kid_workshop kw
    on k.id = kw.kid_id
group by k.id,
         k.name

此查询在执行数据透视时使用了一个技巧。具体来说,它为正面案例分配字符串'true',并为每个负面案例分配'false'。由于'true'在字典上大于'false',因此如果存在,则应使用MAX()函数保留,否则将报告为false。这正是我们想要的逻辑。