【问题标题】:Show only records that bought a specific product without buying another specific product仅显示购买了特定产品而不购买其他特定产品的记录
【发布时间】:2016-10-01 13:25:29
【问题描述】:

我有这个假设的表格

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

我需要提取的是购买了commission fee产品的user_id,而不是monthly planyearly plan,并且只会显示commission fee产品的记录。所以基本上,它会显示这个:

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

谢谢!

【问题讨论】:

标签: mysql


【解决方案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 锁的已知缺陷。)

【讨论】:

    【解决方案2】:

    您可以使用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')
                     );
    

    【讨论】:

      猜你喜欢
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      • 2022-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      相关资源
      最近更新 更多