如何在mysql中在"join"之前使用"group by"?

4

我有一个包含重复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

但是否有一种方法可以在连接之前进行分组?
3个回答

3

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

我不确定LEFT OUTER JOIN是否有用,因为查询返回的唯一字段都来自左侧连接的表。因此,如果某些购买记录没有找到用户,那么您将只返回一堆空行。

但是,执行子查询以获取用户列表并获取所需日期范围内该用户的最大创建日期(虽然在MySQL中不严格必要,但大多数SQL语言都会出错,如果返回的字段不在 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

1
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

希望这有所帮助。

1
严格来说,这将完成所请求的操作,但是结果排序的purchase_key的create_date可能来自用户的任何购买(因此顺序相当无意义),但更糟糕的是,它很可能会排除在所需范围内具有创建日期的购买记录,而选择范围外的记录,从而遗漏记录。 - Kickstart

1
如果你不想看到用户出现多次,尝试在第一行中使用DISTINCT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接