【问题标题】:MySQL - Looking for Top 10 records by MonthMySQL - 按月查找前 10 条记录
【发布时间】:2013-03-21 05:29:49
【问题描述】:

我将介绍表结构:

revshare r : 包含购买信息,包括订单号、销售额、佣金、itemid、EventDate

Products p:包含产品的相关信息,包括 PID(产品 ID),用于加入 Merchants 表以获取 Merchant 信息。

Merchants 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

当我尝试将此查询与另一个查询 UNION 以获取下个月在 '2011-02-01' 和 '2011-02-31' 之间的记录时,我收到错误消息“错误:UNION 和ORDER BY" 我知道这是因为显然您不能在除最后一个之外的任何 UNION 查询集上使用 ORDER BY。我可以提取整个数据集,然后使用 Excel 或 Pentaho BI 仅显示前 10 名,但基于 revshare 表中的庞大数据集,这效率不高。

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

非常感谢任何帮助。

问候, -克里斯

查询 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

【问题讨论】:

  • 您正在调用“按 3 订购”。 order by 指令正在寻找列名。
  • 没有 order by 指令使用列位置或列名,这不是问题。问题是在 UNION 情况下的指令顺序。所以我可以说“ORDER BY 3”或“ORDER BY r.commission”,意思是一样的。
  • 每天学习新东西。

标签: mysql group-by union


【解决方案1】:

好的,试试这个....

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

【讨论】:

  • 完美解决,谢谢 Chuck,我现在看到我需要子查询联合。非常感谢。
【解决方案2】:

既然你已经开始了unioning 查询的路径,那么这里是正确的方法:

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 来标识月份。

【讨论】:

  • 这也行得通,非常感谢 Gordon,再次感谢您对我必须使用子查询的解释。欣赏它。
猜你喜欢
  • 2013-04-24
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 2011-01-24
  • 2021-02-10
  • 2020-03-12
相关资源
最近更新 更多