2013-08-23 44 views
-1

PostgreSQL中是否可以过滤行,以便在某个时间间隔内显示一个与其他表相关的空行。PostgreSQL - 如果相关条件不存在,则选择结果

换句话说想象这个例子:

有两个表partnerscalls

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), 
); 

想想现在吧。在合作伙伴表中创建了一些行。一些呼叫和行出现在呼叫中(呼叫时登记日期)。但我需要过滤相反的东西。如何查看2013-05-01和2013-06-01之间没有电话的合作伙伴?

我不明白的是如何在任何时期过滤不存在​​记录的合作伙伴(如果不需要时间段,那么这很容易,我可以过滤没有呼叫的合作伙伴)?我需要使用外部时间吗?

+1

没有叫'datetime'在Postgres的数据类型。你的意思是'时间戳'? –

+0

@ErwinBrandstetter对不起,我现在更改为时间戳。在openerp中使用datetime,忘记了postgres的名称不同。 – Andrius

回答

2

类似:

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'); 
+0

所以PostgreSQL仍然会检查c.date字段,即使没有任何东西存在,如果你使用'not exists'? – Andrius

+0

@Andrius:当然是(任何DBMS都会这样做)。 –

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; 
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' 
+0

实际上,模式并不真正相关,我只需要知道如何过滤一个与另一个表相关的表,并且在某个时间间隔内其他表不存在行。 – Andrius

+0

@Andrius,那么我会说不存在就是你想要做的。 –

相关问题