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

Using derived table and GROUP BY on 2 columns on MySQL

我正在使用具有某些限制的 MySQL 服务器实例(没有 CTE,无法创建临时 tables 甚至新的 tables),所以唯一的方法允许解决它是使用派生的 tables.

我有以下 table 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      |
+-----------+---------+------------+

我现在取得的成就:如果我有一个类似的table没有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;

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

感谢任何帮助! :)

通过查询生成不同的产品列表。 (如果您有产品 table,您可以参考它。)

只给定问题中的 table,我们可以得到这样一个不同的列表

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

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

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 的其他来源,而不是问题中的 table(例如,具有不同产品列表的产品 table),我们可以请参考它。

诀窍是 "months" 和 "products" 之间的 CROSS JOIN

然后进行外部连接以从 t.

中获取匹配的行