Select 条尚未连接且根据某些列唯一的记录

Select records that are not already joined and are unique basing on some columns

我真的很难用一句话表达清楚我标题中的问题。但这是解释和示例数据:

https://www.db-fiddle.com/f/tfamoNxujZhfTzxPPzefLt/2

create table customer_promotions (
customer_id integer, 
promotion_id integer);

create table promotions (
  promotion_id integer,
  type text,
  product_type text,
  percentage integer);

  insert into customer_promotions values 
  (1,1), 
  (1,5), 
  (2,3),
  (2,4),
  (3,6),
  (4,2);
  insert into promotions values 
  (1,'fixed_value', 'food',5),
   (2,'fixed_value', 'food',10),
    (3,'percentage', 'food',10),
     (4,'percentage', 'clothes',10),
      (5,'fixed_value', 'electronics',20),
       (6,'percentage', 'electronics',10),
        (7,'fixed_value', 'toys',15);

我想为特定客户(假设 customer_id = 1)查找所有尚未使用(存在于 table customer_promotions 中)并且不共享相同 typeproduct_type 已经在使用中。

因此对于客户 1,结果应该是: promotion_id 3个 4个 6个 7 我相信有一些使用 left join 的简单解决方案,但我现在想到的是黑洞。 非常感谢您的帮助。

你可以这样做: 您的字段类型 product_type 使它们成为 varchar(100) 而不是文本。

   select * from promotions a 
   where not exists(select 1 from customer_promotions b 
   where a.promotion_id = b.promotion_id and b.customer_id = 1)
   and not exists
   (select 1 from promotions aa inner join 
   customer_promotions bb on aa.promotion_id = bb.promotion_id 
   where a.type = aa.type and a.product_type  = aa.product_type and bb.customer_id = 1)

输出:

promotion_id    type        product_type    percentage
3             percentage    food            10
4             percentage    clothes         10
6             percentage    electronics     10
7             fixed_value   toys            15

您还需要一个连接来查找特定客户已在使用的促销活动的属性。

select unused.promotion_id, unused.type 
from promotions unused 
left join 
(  
   select promotions.promotion_id, promotions.type, promotions.product_type 
   from promotions inner join customer_promotions 
                   on customer_promotions.promotion_id = promotions.promotion_id
   where customer_id = 1
) used 
         on unused.type = used.type 
            and unused.product_type = used.product_type
where used.promotion_id is null