使用“分组依据”从查询中排除重复项

时间:2010-07-21 13:50:36

标签: sql postgresql

我有三张桌子:

table 'received'
------------------
partner_id int
item_id int

table 'delivered'
------------------
item_id int
delivery_date date
customer_id int

table 'partners'
------------------
id int
name text

table 'customers'
------------------
id int
name text

我想询问的是,哪些合作伙伴在向客户的单次交付中交付了哪些项目。有时,不同的合作伙伴提供相同的项目,这些项目应该被过滤掉,因为交付的项目不包含欺骗项目。

我想出的是:

select 
  partner_id, 
  count(distinct item_id) 
from 
  received 
where item_id in 
  (select distinct item_id from delivered where delivery_date = '2010-07-14' and customer_id = 1)
group by partner_id;

然而,这给了我所有交付的物品,包括合作伙伴提供的欺骗物品。 我已经考虑了很长一段时间了,并尝试使用'除','有'和其他人进行子选择,但没有达到让我更进一步的观点。

我会为任何正确方向的提示而感到高兴。谢谢。

- 编辑 -

以下是一些示例数据:

表'收到'

partner_id | item_id 
-----------|---------
1          | 1
1          | 2
2          | 1
2          | 3

表'已发送'

item_id | delivery_date | customer_id
--------|---------------|------------
1       | 2010-07-14    | 1
2       | 2010-07-14    | 1
3       | 2010-07-14    | 1

目前的输出是:

partner | amount
--------|------
1       | 2
2       | 2

所需的输出是:

partner | amount
--------|------
1       | 2
2       | 1

由于ID 2的合作伙伴已经交付了合作伙伴1已经交付的项目。

2 个答案:

答案 0 :(得分:1)

select 
  partner_id, count(distinct item_id) 
from 
  received join delivered using (item_id)
where 
  delivery_date = '2010-07-14' and customer_id = 1
group by partner_id;

更新后,您的问题似乎没有明确定义。为什么第1项计入一个客户而不是另一个客户?为什么它只计算其中一个,如果两者都交付了它?

您可以尝试:

select 
  partner_id, count(distinct item_id) 
from (
  select distinct on (item_id) partner_id, item_id
  from received join delivered using (item_id)
  where delivery_date = '2010-07-14' and customer_id = 1
  order by item_id, partner_id
)
group by partner_id;

答案 1 :(得分:0)

您必须有理由将每笔交付分配给一个合作伙伴。在您的示例中,您似乎已决定将其分配给较低的数字。你会这样做的:

(在item_id上选择min(partner_id)partner_id,item_id,来自收到的组)rec_assign

然后将交付合作伙伴的partner_id添加到交付的表中:

(从交付中选择已交付。*,rec_assign.partner_id 内连接(选择min(partner_id)partner_id,item_id上的已接收组的item_id)rec_assign on delivered.item_id = rec_assign.item_id))del_mod

现在很简单

选择partner_id,从中计算() (选择交付。,rec_assign.partner_id来自交付 内部联接(选择min(partner_id)partner_id,item_id上的已接收组的item_id)rec_assign on delivered.item_id = rec_assign.item_id))作为del_mod 按partner_id订购的partner_id

我认为应该这样做,模数愚蠢的错误。