基于另一列的MAX从一列中选择DISTINCT

时间:2016-02-24 00:38:13

标签: mysql

我有一个查询返回每个区域中用户的相对活动。我希望返回该列表,但每个用户只在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一次,并使用它是区域的最大应用程序。这样我就有了每个区域的所有最佳表现者的列表,没有重复的用户。

2 个答案:

答案 0 :(得分:0)

您可以尝试包装查询并提取出您想要的内容:

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

答案 1 :(得分:0)

在MySQL中,您有三种基本方法:

  • 使用变量
  • 使用复杂的join
  • 使用substring_index()group_concat()
  • 进行黑客攻击

当您有聚合查询时,复杂join实际上是一团糟。黑客很有趣,但确实有其局限性。所以,让我们考虑一下变量方法:

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,没有HAVING子句和COUNT(*)