SQL group by id然后按日期对结果进行分组

时间:2015-05-05 14:17:04

标签: mysql

我有以下sql语句,但是我想按YEAR(updated_at),MONTH(updated_at)对结果进行分组,并按年份总计给我一个月。那应该做的是找到所有结果,其中order_id不止一次存在,然后为一年中的每个月做一个总计。我想我需要做一个子查询,但我尝试的所有内容都会引发错误。

SELECT  `order_id` ,  `updated_at` , COUNT( * ) AS grand_total1
                FROM mg_sales_flat_shipment_track
                GROUP BY  `order_id` 
                HAVING COUNT( * ) >1
                ORDER BY updated_at DESC

数据集:

entity_id parent_id order_id track_number   title   carrier_code created_at          updated_at
    31468     33349    36055 31237970006263 UK Mail trackerl     2015-05-01 19:30:52 2015-05-01 19:30:52
    31453     33348    36054 31237970006264 UK Mail trackerl     2015-05-01 19:30:49 2015-05-01 19:30:49
    31414     33347    36052 31237970006273 UK Mail trackerl     2015-05-01 19:30:20 2015-05-01 19:30:20
    31469     33346    36050 31237970006265 UK Mail trackerl     2015-05-01 19:30:52 2015-05-01 19:30:52
    31461     33345    36049 31237970006266 UK Mail trackerl     2015-05-01 19:30:47 2015-05-01 19:30:47
    31406     33344    36048 31237970006267 UK Mail trackerl     2015-05-01 19:30:14 2015-05-01 19:30:14
    31404     33343    36047 31237970006268 UK Mail trackerl     2015-05-01 19:30:13 2015-05-01 19:30:13
    31407     33342    36046 31237970006269 UK Mail trackerl     2015-05-01 19:30:15 2015-05-01 19:30:15
    31462     33341    36045 31237970006270 UK Mail trackerl     2015-05-01 19:30:48 2015-05-01 19:30:48
    31405     33340    36044 31237970006271 UK Mail trackerl     2015-05-01 19:30:14 2015-05-01 19:30:14
    31383     33153    35837 31237970006197 UK Mail tracker1     2015-04-30 20:00:43 2015-04-30 20:00:43
    31252     33153    35837 31237970006051 UK Mail tracker1     2015-04-29 20:00:25 2015-04-30 20:00:43

2 个答案:

答案 0 :(得分:0)

您的查询将为您提供不可靠的结果,因为updated_at子句中不包含group by,也不会在聚合函数中使用它。

如果你想要的是有多个条目的所有order_ids,那么每年的每个月计算一次,那么它看起来像这样:

select year(updated_at) y, month(updated_at) m, count(*) from
(  SELECT  `order_id` , COUNT( * ) AS grand_total
                FROM mg_sales_flat_shipment_track
                GROUP BY  `order_id` 
                HAVING COUNT( * ) >1
) q1
inner join mg_sales_flat_shipment_track t
  on q1.order_id = t.order_id
group by year(updated_at), month(updated_at)
order by year(updated_at) desc, month(updated_at) desc;

为了获得更多帮助,您需要提供表格定义,一些示例数据以及您尝试提取的结果。

fiddle here

答案 1 :(得分:0)

我认为你要求的是一个像这样的查询返回的结果集:

SELECT o.order_id
     , DATE_FORMAT(o.updated_at,'%Y-%m') AS `yyyymm`
     , COUNT(1)                          AS `cnt`
  FROM ( SELECT d.order_id
            FROM mg_sales_flat_shipment_track d
           GROUP BY d.order_id
          HAVING COUNT(1) > 1
       ) c
  JOIN mg_sales_flat_shipment_track o
    ON o.order_id = c.order_id
 GROUP
    BY o.order_id
     , DATE_FORMAT(o.updated_at,'%Y-%m')

让我们解开一下。内联视图c基本上为我们提供了多次出现的order_id值列表。由于GROUP BY,这将是不同的列表(每order_id一行)。

我们可以将该内联视图中的行(MySQL称之为“派生表”)连接回表,以获得与列表中的一个匹配的order_id的所有行。我们希望对于每个order_id值,我们将从原始表中获得至少两行。

我们使用DATE_FORMAT函数来获取年份和月份。我们对此进行GROUP BY,并计算每个月的计数。

如果您需要“总计”,我们可以在内联视图中包含COUNT(),然后在外部查询的SELECT列表中引用该列。 order_id的“总计”将在order_id的每一行上重复。

<强>后续

它没有给我每个月的总数

目前尚不清楚你想要的总数。

您可以省略SELECT列表中的order_id列和外部查询中的ORDER BY子句。这将为您提供“月”行的“计数”,其中order_id出现在多行中的所有行。

SELECT DATE_FORMAT(o.updated_at,'%Y-%m') AS `yyyymm`
     , COUNT(1)                          AS `cnt`
  FROM ( SELECT d.order_id
            FROM mg_sales_flat_shipment_track d
           GROUP BY d.order_id
          HAVING COUNT(1) > 1
       ) c
  JOIN mg_sales_flat_shipment_track o
    ON o.order_id = c.order_id
 GROUP
    BY DATE_FORMAT(o.updated_at,'%Y-%m')

此时,我还在猜测你想要返回的结果集。