Использование производной таблицы и GROUP BY на 2 столбца на MySQL - PullRequest
0 голосов
/ 23 мая 2018

Я использую экземпляр MySQL Server с определенными ограничениями (без CTE, не могу создавать временные таблицы или даже новые таблицы), поэтому единственный способ разрешить это - использовать производные таблицы.

Iиметь следующую таблицу 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 голосов
/ 23 мая 2018

Создание отдельного списка продуктов с запросом.(Если у вас есть таблица продуктов, вы можете сослаться на это.)

Учитывая только таблицу в вопросе, мы могли бы получить отдельный список, подобный этому

  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.

...