【问题标题】:MySQL Query to find customers who have ordered two specific productsMySQL 查询以查找订购了两种特定产品的客户
【发布时间】:2013-08-06 04:50:15
【问题描述】:

我无法提出一个查询来查找同时购买了 PROD1 和 PROD2 的所有客户。

这是一个看起来像我想做的伪查询:(显然这行不通)

SELECT COUNT(DISTINCT userid) 
  FROM TRANSACTIONS 
 WHERE product_id = 'prod1' 
   AND product_id = 'prod2'

所以基本上我试图计算在transactions 表中对于product_id 'prod1' 和'prod2' 有事务的不同用户ID 的数量。每个事务都存储在transactions 表中的一行中。

【问题讨论】:

    标签: sql mysql


    【解决方案1】:

    我通过以下方式进行此类查询:

    SELECT COUNT(DISTINCT t1.userid) AS user_count
      FROM TRANSACTIONS t1
      JOIN TRANSACTIONS t2 USING (userid)
     WHERE t1.product_id = 'prod1' 
       AND t2.product_id = 'prod2';
    

    @najmeddine 的GROUP BY 解决方案shown 也可以产生您想要的答案,但它在 MySQL 上的性能不佳。 MySQL 很难优化 GROUP BY 查询。

    您应该尝试这两个查询,使用EXPLAIN 分析优化,并运行一些测试并根据数据库中的数据量对结果进行计时。

    【讨论】:

      【解决方案2】:
      SELECT userid
        FROM TRANSACTIONS
       WHERE product_id in ('prod1', 'prod2')
      GROUP BY userid
      HAVING COUNT(DISTINCT product_id) = 2
      

      【讨论】:

        【解决方案3】:

        (使用用户提供的附加信息在下面添加了新选项)

        试试

        SELECT * FROM Customers WHERE 
         EXISTS (SELECT * FROM Purchases WHERE ProductID = 'PROD1' AND CustID = Customers.CustID)
         AND
         EXISTS (SELECT * FROM Purchases WHERE ProductID = 'PROD2' AND CustID = Customers.CustID)
        

        或者

        SELECT * FROM Customers WHERE 
         CustID IN (SELECT CustID FROM Purchases WHERE ProductID = 'PROD1')
         AND
         CustID IN (SELECT CustID FROM Purchases WHERE ProductID = 'PROD2')
        

        或者

        SELECT UserID FROM Transactions WHERE ProductID = 'PROD1'
         AND EXISTS (SELECT * FROM Transactions WHERE UserID = T1.UserID 
          AND ProductID = 'PROD2')
        

        或者

        SELECT UserID FROM Transactions WHERE ProductID = 'PROD1'
         AND UserID IN (SELECT UserID FROM Transactions WHERE ProductID = 'PROD2')
        

        【讨论】:

          【解决方案4】:

          这是一个基于臭名昭著的 Northwind 示例数据库的 Access 答案。你应该很容易在 mySql 中翻译它。

          SELECT o.CustomerID, Sum([ProductID]='Prod1') AS Expr1, Sum([productid]='Prod1') AS Expr2
          FROM Orders AS o INNER JOIN [Order Details] AS d ON o.OrderID = d.OrderID
          GROUP BY o.CustomerID
          HAVING (((Sum([ProductID]='Prod1'))<>0) AND ((Sum([productid]='Prod1'))<>0));
          

          【讨论】:

            【解决方案5】:
            SELECT COUNT(DISTINCT userId)
            FROM(
              SELECT userId
              FROM transactions
              WHERE product = 'PROD1'
              INTERSECT
              SELECT userId
              FROM transactions
              WHERE product = 'PROD2');
            

            该查询创建了两个中间表,一个包含购买 PROD1 的客户的 userId,另一个包含购买 PROD2 的客户的相同表。 交集运算符返回一个表,其中仅包含在前两个表中找到的行,即购买了这两种产品的人。

            【讨论】:

              【解决方案6】:

              sakila db 示例:

              SELECT R.customer_id, GROUP_CONCAT(I.film_id) 
              FROM sakila.rental R 
              RIGHT OUTER JOIN sakila.inventory I ON R.inventory_id = I.inventory_id 
              WHERE I.film_id IN (22,44) GROUP BY R.customer_id HAVING COUNT(*) = 2
              

              【讨论】:

                猜你喜欢
                • 2011-11-11
                • 2015-12-25
                • 2020-07-30
                • 2013-09-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-10-17
                相关资源
                最近更新 更多