MySQL - 按月查找前10名记录

时间:2013-03-20 20:23:09

标签: mysql group-by union

我将以表结构为前言:

revshare r:包含购买信息,包括orderNo,sales,commission,itemid,EventDate

产品p:包含产品的信息,包括PID(产品ID),用于加入商家表以获取商家信息。

商家m:包含有关购买产品的商家的信息,包括MerchantName

问题

我正在尝试创建一个MySQL查询,以按指定月份的佣金总额排序前10个itemid。我想得到的整个数据集是从2011年到2013年,因此每年将填充120条记录(每月10条)。

我创建了一个查询来提取1个月的数据并计划使用UNION ALL来创建一个记录列表,其中包含来自每个查询的10条记录(每个单独的查询代表一个月前10个itemid的记录)。

查询1

此查询根据给定月份内这些项目的总佣金准确地返回前10个itemid。

SELECT 
m.MerchantName, 
Count(r.OrderNo), 
sum(r.commission)

FROM revshare r
LEFT JOIN Products p ON r.itemid = p.PID
LEFT JOIN Merchants m ON p.MID = m.MID

WHERE r.EventDate between '2011-01-01' and '2011-01-31'

GROUP by r.itemid
ORDER by 3 DESC LIMIT 10

当我尝试将此查询与另一个查询联合以便我可以获取“2011-02-01”和“2011-02-31”之间的下个月的记录时,我得到并且错误“错误:UNION的使用不正确” ORDER BY“我知道这是因为显然你不能在任何一组UNION的查询中使用ORDER BY而是最后一个。我可以提取整个数据集,然后使用Excel或Pentaho BI仅显示前10位,但根据revshare表中的大量数据集效率不高。

以下是UNION ALL的查询不起作用。有没有人有更好的方法来提取这些数据?

非常感谢任何帮助。

此致 -Chris

查询2(由于ORDER BY语句不起作用)

SELECT 
m.MerchantName, 
Count(r.OrderNo), 
sum(r.commission)

FROM revshare r
LEFT JOIN Products p ON r.itemid = p.PID
LEFT JOIN Merchants m ON p.MID = m.MID

WHERE r.EventDate between '2011-01-01' and '2011-01-31'

GROUP by r.itemid
ORDER by 3 DESC LIMIT 10

UNION ALL

SELECT 
m.MerchantName, 
Count(r.OrderNo), 
sum(r.commission)

FROM revshare r
LEFT JOIN Products p ON r.itemid = p.PID
LEFT JOIN Merchants m ON p.MID = m.MID

WHERE r.EventDate between '2011-02-01' and '2011-02-31'

GROUP by r.itemid
ORDER by 3 DESC LIMIT 10

2 个答案:

答案 0 :(得分:2)

好的,试试这个......

SELECT * FROM (
  SELECT 
    m.MerchantName, 
    Count(r.OrderNo), 
    sum(r.commission)
  FROM
    revshare r
    LEFT JOIN Products p ON r.itemid = p.PID
    LEFT JOIN Merchants m ON p.MID = m.MID
  WHERE
    r.EventDate between '2011-01-01' and '2011-01-31'
  GROUP by
    r.itemid
  ORDER by 
    3 DESC LIMIT 10
) AS RESULT1

UNION ALL

SELECT * FROM (
  SELECT 
    m.MerchantName, 
    Count(r.OrderNo), 
    sum(r.commission)
  FROM
    revshare r
    LEFT JOIN Products p ON r.itemid = p.PID
    LEFT JOIN Merchants m ON p.MID = m.MID
  WHERE
    r.EventDate between '2011-02-01' and '2011-02-31'
  GROUP by
    r.itemid
  ORDER by
    3 DESC LIMIT 10
) AS RESULT2

答案 1 :(得分:1)

由于您已经开始union查询的路径,这是正确的方法:

select t.*
from ((SELECT '2011-01' as yyyymm, m.MerchantName, Count(r.OrderNo) as cnt, sum(r.commission) as comm
       FROM revshare r LEFT JOIN
            Products p
            ON r.itemid = p.PID LEFT JOIN
            Merchants m
            ON p.MID = m.MID
       WHERE r.EventDate between '2011-01-01' and '2011-01-31'
       GROUP by r.itemid
       ORDER by comm DESC
       LIMIT 10
      ) union all
      (SELECT '2011-02' as yyyymm, m.MerchantName, Count(r.OrderNo) as cnt, sum(r.commission) as comm
       FROM revshare r LEFT JOIN
            Products p
            ON r.itemid = p.PID LEFT JOIN
            Merchants m
            ON p.MID = m.MID
       WHERE r.EventDate between '2011-02-01' and '2011-02-28'
       GROUP by r.itemid
       ORDER by comm DESC LIMIT 10
      ) union all
      . . .
     ) t
order by 1, comm desc

换句话说,您需要使用union all的子查询。请注意,我还在yyyymm中添加了以确定月份。