我有一张这样的表:
buyer product quantity
tom skirt 2
anna skirt 3
tom jeans 5
distinct(product) = skirt
和jeans
如果所有可能的产品都不存在quantity = 0
元组,我想要一个用<buyer, product>
插入另一列的表。
结果将是:
buyer product quantity
tom skirt 2
anna skirt 3
tom jeans 5
anna jeans 0
它看起来并不复杂,但我不知道该怎么做。
UPDATE
我发现了一个额外的并发症。
我的产品实际上由两个字段定义:类和产品。产品可以为null,当产品字段为空时,我不需要丢失信息量(现在它发生在交叉连接中)。
所以,如果我有这个:
buyer class product quantity
tom clothes skirt 2
anna clothes skirt 3
tom clothes jeans 5
jim shoes NULL 7
我需要:
buyer class product quantity
tom clothes skirt 2
anna clothes skirt 3
tom clothes jeans 5
anna clothes jeans 0
jim shoes NULL 7
jim clothes skirt 0
jim clothes jeans 0
tom shoes NULL 0
anna shoes NULL 0
谢谢大家,我知道我的事情变得复杂了!
答案 0 :(得分:3)
您可以使用cross join
生成所有可能的买方和产品组合。然后使用left join
(或not exists
)过滤掉表格中已有的内容:
insert into table(buyer, product, quantity)
select b.buyer, p.product, 0
from (select distinct buyer from table) b cross join
(select distinct product p from table) p left join
table t
on t.buyer = b.buyer and t.product = p.product
where t.buyer is null;
编辑:
如果您想要一个返回所有行的查询,那么您将使用非常相似的东西:
select b.buyer, p.product, coalesce(t.qty, 0) as qty
from (select distinct buyer from table) b cross join
(select distinct product p from table) p left join
table t
on t.buyer = b.buyer and t.product = p.product;
编辑II:
如果您有买家和/或产品的NULL
值,请使用NULL
安全比较:
select b.buyer, p.product, coalesce(t.qty, 0) as qty
from (select distinct buyer from table) b cross join
(select distinct product p from table) p left join
table t
on t.buyer is not distinct from b.buyer and
t.product is not distinct from p.product;
(作为次要的注意事项:我真的不喜欢在这个结构中使用distinct
。为什么Postgres(ANSI?)给它这么复杂的名字?)
答案 1 :(得分:1)
@Gordon的解决方案几乎已满,我编辑如下:
declare @tb table (buyer varchar(150), product varchar(150), quantity int)
insert into @tb
values('tom','skirt',2),
('anna','skirt',3),
('tom','jeans',5)
select *
from @tb a
left join( select
distinct(product)
from @tb) b on a.product = a.product
select b.buyer, p.p, isnull(t.quantity,0)
from (select distinct buyer from @tb) b cross join
(select distinct product p from @tb) p left join
@tb t
on t.buyer = b.buyer and t.product = p.p
--where t.buyer is null
试试吧。