MySQL - 从一个具有不同Order和Limit的查询设置的两个记录

时间:2014-01-14 14:15:55

标签: mysql sql limit

我不知道我想做什么是可能的,但让我揭露我的问题。 我有一个这样的查询:

SELECT 
    SUM(report.impressions) AS impressions,
    SUM(report.revenue) AS revenue,
    report.country AS country
FROM
    report_table report
WHERE
    date >= '2014-01-01'
        AND date <= '2014-01-31'
GROUP BY report.country
ORDER BY revenue DESC
LIMIT 0 , 5

此查询为我提供了收入最高的5条记录。我还希望拥有最高展示次数的5条记录。这是此查询的结果:

SELECT 
    SUM(report.impressions) AS impressions,
    SUM(report.revenue) AS revenue,
    report.country AS country
FROM
    report_table report
WHERE
    date >= '2014-01-01'
        AND date <= '2014-01-31'
GROUP BY report.country
ORDER BY impressions DESC
LIMIT 0 , 5

我的问题是我不想两次执行相同的查询,因为必须再次重新计算SUM。 有没有办法让收入排名前5,印象排名前5,而不必两次得到这笔钱? (我不需要两次获得相同的记录)。或者,为了获得最高性能,最好的方法是什么? (因为我可以只做我的两个请求的UNION,但这似乎不是最优化的)

答案: 这是我的问题的可行解决方案:

    SELECT impressions, 
    revenue, 
    country,
    @rn := if (@n = n,@rn + 1,1) AS seqnum,
    @n := n AS dn 
    FROM (
    SELECT SUM(report.impressions) AS impressions, 
            SUM(report.revenue) AS revenue, 
            report.country AS country, 
            n 
        FROM country_report report 
        cross join (select 1 as n union all select 2) n 
        cross join (select @rn := 0, @n := 1) m 
        WHERE date >= "2014-01-01" AND date <= "2014-01-31" 
        GROUP BY n,report.country 
        ORDER BY n,(case when n = 1 then revenue else impressions end) DESC 
    ) r 
    WHERE if (@n = n,@rn + 1,1) <=5

2 个答案:

答案 0 :(得分:0)

以下是一种获取完整列表的方式,首先按收入排序,然后按展示次数排序

SELECT SUM(report.impressions) AS impressions, SUM(report.revenue) AS revenue,
       report.country AS country
FROM report_table report cross join
     (select 1 as n union all select 2) n
WHERE date >= "2014-01-01" AND date <= "2014-01-31"
GROUP BY n, report.country
ORDER BY (case when n = 1 then revenue else impressions end) DESC;

现在的问题是从每个组中获取前五个值。您可以使用子查询执行此操作:

select impressions, revenue, country
from (SELECT SUM(report.impressions) AS impressions, SUM(report.revenue) AS revenue,
             report.country AS country,
             @rn := if (@n = n then @rn + 1 else 1 end) as seqnum,
             @n := n
      FROM report_table report cross join
           (select 1 as n union all select 2) n cross join
           (select @rn := 0, @n := -1)
      WHERE date >= "2014-01-01" AND date <= "2014-01-31"
      GROUP BY n.n, report.country
      ORDER BY n.n, (case when n.n = 1 then revenue else impressions end) DESC
     ) r
where seqnum <= 5;

答案 1 :(得分:0)

如果您愿意,您也可以通过这种方式获得最大的五次展示和收入。这将与您查询的次数完全相同。

(SELECT 
        SUM(report.impressions) AS impressions,
        report.country AS country
    FROM
        report_table report
    WHERE
        date >= '2014-01-01'
            AND date <= '2014-01-31'
    GROUP BY report.country
    ORDER BY impressions DESC
    LIMIT 0 , 5)
    Union
    (SELECT 
        SUM(report.revenue),
        report.country
    FROM
        report_table report
    WHERE
        date >= '2014-01-01'
            AND date <= '2014-01-31'
    GROUP BY report.country
    ORDER BY revenue DESC
    LIMIT 0 , 5)