我正在使用Postgres 9.6。我的数据库包含属于用户的演示文稿。每个演示文稿都有很多幻灯每个幻灯片可以可选地具有背景图像。
Table "public.presentation"
id │ integer
user_id │ integer
Table "public.slide"
id | integer
presentation_id | integer (foreign key)
index | integer
Table "public.background"
slide_id . | integer (foreign key)
image_id │ integer
我想检索特定用户的演示文稿列表,以及每个演示文稿的名称和ID,我想获得具有背景图像的第一张幻灯片的背景图像的ID(或者如果它的幻灯片都没有背景图像,则返回null)。这样我就可以在每个演示文稿旁边显示缩略图。
目前我有一个查询只能获取演示文稿中第一张幻灯片的背景图片ID:
SELECT presentation.*, background.image_id
FROM presentation
JOIN -- get the first slide in each presentation
(SELECT presentation_id FROM slide WHERE index=0)
ON slide.presentation_id=presentation.id
LEFT OUTER JOIN -- join this with background (even if null)
background ON background.slide_id=slide.id
WHERE presentation.user_id=100
ORDER BY presentation.id;
但我想更改此设置以获取每个演示文稿的第一个非空背景图像ID。不知道怎么做!
我想知道Postgres的first_value
能否以某种方式帮助我?
答案 0 :(得分:1)
select *
from
presentation
left join (
select
b.image_id, s.presentation_id as id,
row_number() over (
partition by s.presentation_id
order by s.index
) as rn
from
slide s
inner join
background b on b.slide_id = s.id
) b using (id)
where rn = 1 or rn is null
答案 1 :(得分:0)
看起来就像你只需要两列就能获得你所遗漏的信息。
select slide.presentation_id, min(background.image_id) as background_image_id
from slide
left join background
on slide.id = background.slide_id
group by slide.presentation_id
order by slide.presentation_id, background_image_id;
这为每个演示文稿提供了一行。
with first_background_image as (
select slide.presentation_id, min(background.image_id) as background_image_id
from slide
left join background
on slide.id = background.slide_id
group by slide.presentation_id
), first_slide as (
select presentation_id, min(index) as first_slide_id
from slide
group by presentation_id
)
select fs.presentation_id, fs.first_slide_id, fbi.background_image_id
from first_slide fs
left join first_background_image fbi
on fbi.presentation_id = fs.presentation_id
order by presentation_id;
您应该在问题中包含CREATE TABLE和INSERT语句。
create table presentation (
id integer primary key,
user_id integer not null
);
create table slide (
id integer primary key,
presentation_id integer not null
references presentation (id),
index integer not null,
unique (presentation_id, index)
);
create table background (
-- Assumes one background per slide.
slide_id integer primary key
references slide (id),
image_id integer not null
-- references something?
);
insert into presentation values (1, 1), (2, 1), (3, 2);
insert into slide values (1, 1, 1), (2, 1, 2), (3, 1, 3), (4, 2, 1), (5, 2, 2), (6, 3, 1);
insert into background values (1, 3), (2, 7), (5, 18);