我使用具有某些约束的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或临时表。
任何帮助表示赞赏! :)
答案 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
的匹配行。