2015-11-04 83 views
0

我有以下包含重复的user_id的查询。我不想看到一个以上的用户。我决定使用如下组合:如何在mysql的“join”之前使用“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 

但是有没有办法在连接之前做这样的分组?

回答

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 

希望这有助于

+0

虽然严格来说,这将做的是要求什么,对于purchase_key的CREATE_DATE该结果由排序可能来自用户的任何购买(因此订单非常没有意义),但更糟糕的是,它可能会排除购买记录,并且创建日期在所需范围内,而不是范围之外的购买记录,因此缺少记录。 – Kickstart

0

如果你不希望看到用户不止一次,尝试在第一线使用DISTINCT

0

不知道你为什么想这样做。除非指数非常差,否则它不会对绩效有所帮助。

不确定LEFT OUTER JOIN是否有用,因为您查询返回的唯一字段是左连接表中的字段。因此,如果没有找到用户进行某些购买,那么您只需要返回一行空行。

但是,通过子查询获取用户列表,并在所需的日期范围内为该用户创建最大日期(虽然对MySQL的大多数SQL来说不是绝对必要的,但如果返回的字段是不是在INNER JOIN GROUP BY子句,而不是总场),并使用为您提供了以下内容: -

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