-1

Is it possible in PostgreSQL to filter rows in way that it would show one table rows that are related with other tables empty rows in some time interval.

In other words imagine this example:

There are two tables partners and calls.

create table partners(
    id int,
    name varchar(100),
    call_id references calls (id),
    PRIMARY KEY (id)
);

create table calls(
    id int,
    name varchar(100),
    date timestamp,
    PRIMARY KEY (id),
);

So imagine this now. There are some rows created in partners table. Some calls made and rows appeared in calls (where date is registered when calls were made). But I need to filter the opposite. How to see partners that has no calls let say in dates between 2013-05-01 and 2013-06-01?

What I don't get it is how to filter partners with non existent records in any period (if period wouldn't be required, then it would be easy. I could just filter partners which have no calls)? Do I need to use external time or something?

4

3 回答 3

3

就像是:

select p.*
from partners p
where not exists (select 1 
                  from calls c
                  where c.name = p.name 
                    and c.date between DATE '2013-05-01' and DATE '2013-06-01');
于 2013-08-23T11:21:58.100 回答
1

你的架构对我来说看起来很奇怪。为什么合作伙伴有一个参考调用?我会说它应该是这样的:

create table partners(
    id int,
    name varchar(100),
    PRIMARY KEY (id)
);

create table calls(
    id int,
    date datetime,
    partner_id references partners (id),
    PRIMARY KEY (id),
);

你的查询就像

select p.*
from partners as p
where
    not exists
    (
        select *
        from calls as c
        where c.partner_id = p.id and c.date between '2013-05-01' and '2013-06-01'
    )

如果您想保留当前架构,那么您的查询可以采用所有不同的合作伙伴名称,然后排除在给定时间段内有呼叫的人:

select distinct p.name
from partners as p
except
select distinct p.name
from partners as p
    inner join calls as c on c.id = p.call_id
where c.date between '2013-05-01' and '2013-06-01'

如果合作伙伴和呼叫之间没有联系,而您只想从呼叫表中排除名称(我说过,架构真的很奇怪 :)

select distinct p.name
from partners as p
except
select distinct c.name
from calls as c
where c.date between '2013-05-01' and '2013-06-01'
于 2013-08-23T11:21:57.567 回答
0

你有一个非常神秘的数据结构。一个名为的表partners应该每个合作伙伴有一行。您所说的合作伙伴实际上应该是另一张桌子。

因此,首先要做的是获取合作伙伴列表。然后用于left outer join连接到其他表。如果没有匹配,则保留行:

select p.*
from (select distinct name
      from partners
     ) as allpartners left outer join
     p
     on p.name = allpartners.name left outer join
     calls c
     on p.call_id = c.id and
        c.date between DATE1 and DATE2
where c.name is NULL;
于 2013-08-23T11:21:15.440 回答