繁体   English   中英

SQL(Postgres)查询问题:内连接去掉了一些必要的值

[英]SQL (Postgres) query problem : Inner joining removes some necessary values

我有 3 个这样定义的表

CREATE TABLE participants(
    id SERIAL PRIMARY KEY,
    Name TEXT NOT NULL,
    Title TEXT NOT NULL
);

CREATE TABLE meetings (
    id SERIAL PRIMARY KEY,
    Subject TEXT NOT NULL,
    Organizer TEXT NOT NULL,
    StartTime TIMESTAMP NOT NULL,
    EndTime TIMESTAMP NOT NULL
);

CREATE TABLE meetings_participants(
    meeting_id int not null,
    participant_id int not null,
    primary key (meeting_id, participant_id),
    constraint fk_meeting_id foreign key(meeting_id) references meetings(id),
    constraint fk_participant_id foreign key(participant_id) references participants(id)
);

我想找到今天发生的有参与者参加的会议。 当我运行这个查询时,我基本上得到了它们

SELECT * from meetings 
inner join meetings_participants on meetings.id = meetings_participants.meeting_id 
inner join participants on meetings_participants.participant_id = participants.id 
WHERE starttime::date = NOW()::date;

问题是这个查询丢弃了还没有参与者的会议,我仍然希望将它们包含到我的查询结果中。 如何修改我的查询以使其工作?

您需要 LEFT JOIN 而不是 INNER。 使用::date 转换意味着您只对他们今天发生的事情感兴趣,无论它是否已经结束。 您仍然应该在查询中包含 EndTime,考虑到可能会有跨越几天的会议:

SELECT * from meetings 
left join meetings_participants on meetings.id = meetings_participants.meeting_id 
left join participants on meetings_participants.participant_id = participants.id 
WHERE starttime::date <= NOW()::date and endtime::date >= NOW()::date ;

DBFiddle 演示在这里。

您没有提到您是否希望每个参与者在单独的行上或作为一个集合(例如逗号分隔的列表)。 如果是前者,则将内部更改为左联接。 对于后一种情况,您可以:

SELECT meetings.*, (
    SELECT string_agg(participants.name, ', ')
    FROM meetings_participants
    JOIN participants ON meetings_participants.participant_id = participants.id
    WHERE meetings_participants.meeting_id = meetings.id
) AS participants_list
FROM meetings 
WHERE starttime::date = current_date

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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