完成不存在行的表

时间:2015-05-15 16:44:20

标签: sql postgresql

我有一张这样的表:

buyer        product        quantity
tom          skirt          2
anna         skirt          3
tom          jeans          5

distinct(product) = skirtjeans

如果所有可能的产品都不存在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

谢谢大家,我知道我的事情变得复杂了!

2 个答案:

答案 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

试试吧。