MySQL динамическая перекрестная таблица по двум столбцам - PullRequest
0 голосов
/ 02 августа 2011

Дамы и господа,

У меня следующая проблема в MySQL 5.1. Вот мой стол.

Sale | Store | Product | Discount
---------------------------------
 1   |   1   |   B     | Yes
 2   |   1   |   B     | Yes
 3   |   1   |   B     | No
 4   |   1   |   D     | Yes
 5   |   1   |   A     | No
 6   |   2   |   A     | No
 7   |   3   |   B     | No
 8   |   3   |   B     | No
 9   |   1   |   D     | Yes
10   |   2   |   A     | No

Теперь это, конечно, очень неудобный способ организации данных, но именно так данные поступили (и будут поступать).

Мне нужно иметь возможность выдавать совершенно произвольный список типов продуктов (разделенных запятыми, если хотите); скажем A,B,C. В конце концов, мне нужен список того, что магазин продал что. Вот промежуточный результат, чтобы его было легче понять.

Store | Product | Sales | Discounts
-----------------------------------
  1   |   A     |  1    | 0
  1   |   B     |  3    | 2
  1   |   C     |  0    | 0
  2   |   A     |  2    | 0
  2   |   B     |  0    | 0
  2   |   C     |  0    | 0
  3   |   A     |  0    | 0
  3   |   B     |  2    | 0
  3   |   C     |  0    | 0

В конце концов мне нужно следующее:

Store | Product types sold | Discounts given on product types:
-------------------------------------------------------------
  1   |         2          |        1
  2   |         1          |        0
  3   |         1          |        0

В третьем столбце указано, какому количеству проданных (и запрошенных) типов продуктов была предоставлена ​​хотя бы одна скидка.

Я пробовал все виды динамических запросов на создание кросс-таблиц (да, я видел их все), но у меня недостаточно умственной оперативной памяти, чтобы обернуть все вокруг за один раз. Как бы вы подошли к этому наиболее эффективным способом? Временные таблицы / хранимые процедуры и т. Д. В порядке, грубые наброски идей очень приветствуются. Спасибо!

Ответы [ 2 ]

3 голосов
/ 02 августа 2011

Вы можете сгруппировать данные по магазинам и продуктам, чтобы получить промежуточный результат:

mysql> SELECT Store, Product,
COUNT(1) AS Sales,
SUM(IF(Discount='Yes', 1, 0)) AS Discounts
FROM input
WHERE Product IN ('A', 'B', 'C', 'D')
GROUP BY Store, Product
+-------+---------+-------+-----------+
| Store | Product | Sales | Discounts |
+-------+---------+-------+-----------+
|     1 | A       |     1 |         0 |
|     1 | B       |     3 |         2 |
|     1 | D       |     2 |         2 |
|     2 | A       |     2 |         0 |
|     3 | B       |     2 |         0 |
+-------+---------+-------+-----------+
5 rows in set (0.00 sec)

Затем вы можете сгруппировать этот результат по магазинам, чтобы преобразовать его в конечный результат:

mysql> SELECT Store,
COUNT(1) AS `Product types sold`,
SUM(Discounts) AS `Discounts given on product types`
FROM (
SELECT Store, Product,
COUNT(1) AS Sales,
SUM(IF(Discount='Yes', 1, 0)) AS Discounts
FROM input
WHERE Product IN ('A', 'B', 'C', 'D')
GROUP BY Store, Product
) AS intermediate
GROUP BY Store
+-------+--------------------+----------------------------------+
| Store | Product types sold | Discounts given on product types |
+-------+--------------------+----------------------------------+
|     1 |                  3 |                                4 |
|     2 |                  1 |                                0 |
|     3 |                  1 |                                0 |
+-------+--------------------+----------------------------------+
3 rows in set (0.00 sec)

Обратите внимание, что первый запрос является подзапросом второго.

1 голос
/ 02 августа 2011

Я думаю, просто разделить запросы проще всего:

select Store, 
   (Select count( distinct Product) from products as p2 where p2.Store = p1.Store),
   (Select count(distinct Product) from products as p3 where p3.Store = p1.Store and p3.Discount = "Yes")
from products p1
group by Store

(Если речь идет о больших таблицах, обязательно проверьте свою производительность.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...