Я использую экземпляр 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 или временные таблицы.
Любая помощь приветствуется! :)
Создайте отдельный список продуктов с запросом. (Если у вас есть таблица продуктов, вы можете ссылаться на это.)
Учитывая только таблицу в вопросе, мы могли бы получить отдельный список, подобный этому
SELECT q.product
FROM t q
GROUP
BY q.product
Мы можем обернуть это в parens как встроенное представление (производную таблицу на языке 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
и выполнить GROUP BY и агрегировать в списке SELECT...
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
.