仅显示购买特定产品而不购买其他特定产品的记录

时间:2016-06-02 01:13:29

标签: mysql

我有这个假设的表格

transac_id     user_id        product
----------     -------        -------
  2051613       189546      monthly plan
  8746169       189546      commission fee
  7845946       998741      commission fee
  8897155       166235      sms
  6325477       166235      newsletter
  8897452       166235      commission fee
  4328941       302604      monthly plan
  8897415       309888      sms
  2564718       960007      commission fee
  7451352       960007      yearly plan

我需要提取的是user_id已购买commission fee产品,而不是monthly planyearly plan,并且仅显示commission fee的记录1}}产品。所以基本上,它会显示出来:

 transac_id     user_id         product
 ----------     -------         -------
  7845946       998741      commission fee
  8897155       166235      commission fee.

谢谢!

2 个答案:

答案 0 :(得分:1)

要查找多对多表中具有值为a的行的特定属性但没有值为b的行的实体,您可以执行不存在的自连接。这是自身的LEFT JOIN表,其中连接条件指定相同的实体和值b。 (在LEFT JOIN中,如果左表中的行在右表中没有对应的行,则该行中右表中的所有列都将为NULL。)然后查询仅保留行右表的主键IS NULL,只能在这样一个不存在的行中发生。

SELECT cft.transac_id, cft.user_id, cft.product
FROM transactions cft
LEFT JOIN transactions myp
ON (cft.user_id = myp.user_id
    AND myp.product IN ('monthly plan', 'yearly plan'))
WHERE cft.product = 'commission fee'
  AND myp.transac_id IS NULL

(在MySQL中,如果表是TEMPORARY,则自联接需要使用second copy of the data in another TEMPORARY TABLE来解决MySQL锁中已知的缺陷。)

答案 1 :(得分:0)

您可以使用group byhaving

来吸引此类用户
select user_id
from t
group by user_id
having sum(product = 'commission fee') > 0 and
       sum(product = 'monthly plan') = 0 and
       sum(product = 'yearly plan') = 0;

然后,您可以使用以下逻辑获取原始行:

select t.*
from t
where t.product = 'commission fee' and
      t.user_id in (select user_id
                    from t
                    group by user_id
                    having sum(product = 'commission fee') > 0 and
                           sum(product = 'monthly plan') = 0 and
                           sum(product = 'yearly plan') = 0
                   );

另一种方法使用not exists

select t.*
from t
where t.product = 'commission fee' and
      not exists (select 1
                  from t t2
                  where t2.user_id = t.user_id and
                        t2.product in ('monthly plan', 'yearly plan')
                 );