在MySQL上的2列上使用派生表和GROUP BY

时间:2018-05-23 14:57:04

标签: mysql group-by count derived-table

我使用具有某些约束的MySQL Server实例(没有CTE,无法创建临时表甚至新表),因此允许解决它的唯一方法是使用派生表。

我有下表t,其中包含每个月(1-12)每次销售的每次出现:

+------+-----------+-----------------+
|  id  |  product  |  sold_on_month  |
+------+-----------+-----------------+
|   1  | Product 1 |        1        |
|   2  | Product 1 |        2        |
|   3  | Product 1 |        2        |
|   4  | Product 1 |        3        |
|   5  | Product 1 |        3        |
|   6  | Product 1 |        4        |
|   7  | Product 1 |        4        |
|   8  | Product 1 |        4        |
|   9  | Product 1 |        4        |
|  10  | Product 1 |        4        |
|  11  | Product 2 |        1        |
|  12  | Product 2 |        1        |
|  13  | Product 2 |        2        |
|  14  | Product 2 |        2        |
|  15  | Product 2 |        3        |
|  16  | Product 2 |        3        |
+------+-----------+-----------------+

我想创建一个查询来回答我按产品和按月销售的产品数量,如下所示:

+-----------+---------+------------+
|  product  |  month  |  how_many  |
+-----------+---------+------------+
| Product 1 |    1    |     1      |
| Product 1 |    2    |     2      |
| Product 1 |    3    |     2      |
| Product 1 |    4    |     5      |
| Product 1 |    5    |     0      |
| Product 1 |    6    |     0      |
| Product 1 |    7    |     0      |
| Product 1 |    8    |     0      |
| Product 1 |    9    |     0      |
| Product 1 |   10    |     0      |
| Product 1 |   11    |     0      |
| Product 1 |   12    |     0      |
| Product 2 |    1    |     2      |
| Product 2 |    2    |     2      |
| Product 2 |    3    |     2      |
| Product 2 |    4    |     0      |
| Product 2 |    5    |     0      |
| Product 2 |    6    |     0      |
| Product 2 |    7    |     0      |
| Product 2 |    8    |     0      |
| Product 2 |    9    |     0      |
| Product 2 |   10    |     0      |
| Product 2 |   11    |     0      |
| Product 2 |   12    |     0      |
+-----------+---------+------------+

我现在取得的成就:如果我有一个类似的表没有product,如果我想按月分组,那么查询就是这个:

SELECT
  a.mn, COUNT(t.sold_on_month)
FROM
  (SELECT 1 AS mn UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8
   UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) AS a
  LEFT JOIN t
    ON t.sold_on_month = a.mn
GROUP BY a.mn;

所以,我真正需要的是一个查询,它使用相同的派生表来计算月份,按产品和sold_on_month分组,在0列上显示how_many当月没有产品销售时。记住我不能使用CTE或临时表。

任何帮助表示赞赏! :)

1 个答案:

答案 0 :(得分:1)

使用查询生成不同的产品列表。 (如果您有产品表,则可以参考。)

只给出问题中的表格,我们可以得到一个像这样的独特列表

  SELECT q.product
    FROM t q
   GROUP
      BY q.product

我们可以将它作为内联视图(在MySQL的说法中用派生表)包装在parens中,然后交叉连接到生成的月份列表,

SELECT p.product
     , a.mn
  FROM ( -- distinct list of products 
         SELECT q.product
           FROM t q
          GROUP
             BY q.product
       ) p
 CROSS
  JOIN ( -- list of months
         SELECT 1 AS mn UNION ALL ... 
       ) a
 ORDER
    BY p.product
     , a.mn 

然后我们可以将外部联接添加到t,并在SELECT列表中执行GROUP BY并聚合...

SELECT p.product
     , a.mn
  -- , IFNULL(SUM(t.qty),0)    AS tot_qty
     , COUNT(t.sold_on_month)  AS cnt_rows
  FROM ( -- distinct list of products
         SELECT q.product
           FROM t q
          GROUP
             BY q.product
       ) p
 CROSS
  JOIN ( -- list of months
         SELECT 1 AS mn UNION ALL ... 
       ) a
  LEFT
  JOIN t t
    ON t.product       = p.product
   AND t.sold_on_month = a.mn 
 GROUP
    BY p.product
     , a.mn
 ORDER
    BY p.product
     , a.mn

如果你有内联视图p的其他来源,而不是问题中的表格(例如,产品表中包含不同的产品列表),我们可以参考该来源。

诀窍是“月”和“产品”之间的CROSS JOIN

然后使用外部联接来获取t的匹配行。