繁体   English   中英

根据另一列的MAX从一个列中选择DISTINCT

[英]SELECT DISTINCT from one column based on MAX of another

我有一个查询,返回每个区域中用户的相对活动。 我希望返回该列表,但每个用户仅位于1个区域中,因此我想过滤每个人的MAX应用程序。

当前查询:

SELECT 
    r.region_id,
    ha.user_id,
    count(ha.user_id) AS applications 
FROM 
    sit_applications ha
LEFT JOIN 
    listings_regions r 
        ON 
            r.listingID = ha.listingID
            AND deleted = 0
WHERE 
    ha.datetime_applied >= (NOW() - INTERVAL 1 MONTH) 
GROUP BY 
    ha.user_id, r.region_id
HAVING 
    applications > 0
ORDER BY 
    r.region_id DESC

我需要过滤此查询,因此我只获取每个user_id一次,并且它是该地区最大的应用程序。 这样一来,我可以列出每个区域的所有最佳执行者,并且没有重复的用户。

您可以尝试包装查询并提取所需内容:

SELECT t2.user_id, t2.region_id, t2.applications
FROM
(
    SELECT t.user_id, MAX(t.applications) AS applications
    FROM
    (
        SELECT r.region_id, ha.user_id, COUNT(ha.user_id) AS applications 
        FROM sit_applications ha LEFT JOIN listings_regions r 
            ON r.listingID = ha.listingID AND deleted = 0
        WHERE ha.datetime_applied >= (NOW() - INTERVAL 1 MONTH) 
        GROUP BY ha.user_id, r.region_id
        HAVING applications > 0
    ) t
    GROUP BY t.user_id
) t1
INNER JOIN
(
    SELECT r.region_id, ha.user_id, COUNT(ha.user_id) AS applications 
    FROM sit_applications ha LEFT JOIN listings_regions r 
        ON r.listingID = ha.listingID AND deleted = 0
    WHERE ha.datetime_applied >= (NOW() - INTERVAL 1 MONTH) 
    GROUP BY ha.user_id, r.region_id
    HAVING applications > 0
) t2
    ON t1.user_id = t2.user_id AND t1.applications = t2.applications

在MySQL中,您可以通过三种基本方法来执行此操作:

  • 使用变量
  • 使用复杂的join
  • substring_index()group_concat()使用hack。

当您有聚合查询时,复杂的join确实是一团糟。 hack很有趣,但是确实有其局限性。 因此,让我们考虑变量方法:

SELECT ur.*
FROM (SELECT ur.*,
             (@rn := if(@u = user_id, @rn + 1,
                        if(@u := user_id, 1, 1)
                       )
             ) as rn
      FROM (SELECT r.region_id, ha.user_id, count(ha.user_id) AS applications 
            FROM sit_applications ha LEFT JOIN 
                 listings_regions r 
                 ON r.listingID = ha.listingID AND deleted = 0
            WHERE ha.datetime_applied >= (NOW() - INTERVAL 1 MONTH) 
            GROUP BY ha.user_id, r.region_id
            HAVING applications > 0
           ) ur CROSS JOIN
           (SELECT @u := -1, @rn := 0) params
      ORDER BY user_id, applications DESC
     ) ur
WHERE rn = 1;

注意:即使我保留了查询的内容,它们也没有任何意义。您使用的是LEFT JOIN ,因此r.region_id可能为NULL ,这通常是不希望的。 您有一个完全不需要的HAVING子句,因为COUNT()始终为1-假设ha.user_id永远不会为NULL 我怀疑可以用INNER JOIN ,no HAVING子句和COUNT(*)代替逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM