【问题标题】:How to use "group by" before "join" on mysql?如何在mysql上的“加入”之前使用“group by”?
【发布时间】:2016-02-04 17:59:18
【问题描述】:

我有以下查询,其中包含重复的 user_id。我不想看到一个以上的用户。我决定使用 group by,如下所示:

SELECT u.`ID`, u.`user_login`, u.`user_registered`, u.`display_name` 
FROM purchase_key p 
LEFT JOIN users u ON p.user_id = u.id  
WHERE  (  `product_id` = 1 OR  `product_id` = 2 )  
AND  `create_date` <= '2015-09-20'   AND  `create_date` >= '2014-09-01'  
group by p.user_id order by p.`create_date` asc

但是有没有办法在加入之前进行分组?

【问题讨论】:

    标签: mysql join group-by


    【解决方案1】:

    不确定您为什么要这样做。除非索引很差,否则它不太可能有助于提高性能。

    不确定 LEFT OUTER JOIN 是否有用,因为您的查询返回的唯一字段是来自左连接表的字段。因此,如果没有为某些购买找到用户,您只会返回大量空行。

    但是执行子查询以获取用户列表,该用户的最大创建日期在所需的日期范围内(虽然对于 MySQL 来说不是绝对必要的,但如果您返回的字段不是在 group by 子句中而不是聚合字段中),并使用 INNER JOIN 为您提供以下内容:-

    SELECT u.ID, u.user_login, u.user_registered, u.display_name 
    FROM 
    (
        SELECT user_id, MAX(create_date) AS max_create_date
        FROM purchase_key 
        WHERE  product_id IN (1, 2)  
        AND  create_date BETWEEN '2014-09-01' AND '2015-09-20'
        GROUP BY user_id 
    ) p 
    INNER JOIN users u ON p.user_id = u.id  
    ORDER BY p.max_create_date ASC
    

    【讨论】:

      【解决方案2】:
      SELECT u.`ID`, u.`user_login`, u.`user_registered`, u.`display_name` 
      FROM (SELECT * FROM purchase_key GROUP BY user_id ) p 
      LEFT JOIN users u ON p.user_id = u.id  
      WHERE  (  `product_id` = 1 OR  `product_id` = 2 )  
      AND  `create_date` <= '2015-09-20'   AND  `create_date` >= '2014-09-01'  
       order by p.`create_date` asc
      

      希望对你有帮助

      【讨论】:

      • 虽然严格来说这将满足​​要求,但结果所订购的 purchase_key 的 create_date 可能来自用户的任何购买(因此订单毫无意义),但更糟糕的是可能会排除创建日期在所需范围内的购买记录,而选择范围外的购买记录,因此会丢失记录。
      【解决方案3】:

      如果您不想多次看到用户,请尝试在第一行中使用DISTINCT

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-07
        • 2016-04-03
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        • 2018-06-27
        • 2017-11-14
        • 1970-01-01
        相关资源
        最近更新 更多