Сводная таблица из 3 таблиц с Dynami c Value - PullRequest
0 голосов
/ 04 августа 2020

Я хочу создать сводную таблицу, используя следующую таблицу, но перед этим вот моя таблица

tbl_branch

enter image description here

tbl_product

enter image description here

tbl_orders

enter image description here

Now. all of them are dynamic, means soon I will add new branch,new item and the orders will continue. and now here is the output I want to achieve.

введите описание изображения здесь

Как я могу добавить общее количество по ветке и позиции? По сути, это сводная таблица. Было бы легко, если бы это было c, но 3 таблицы будут продолжать добавлять данные.

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Пример запроса сводной таблицы выглядит следующим образом:

select p.description as item,
  sum(case o.branch_id when 1 then o.qty else 0 end) as `Branch 1`,
  sum(case o.branch_id when 2 then o.qty else 0 end) as `Branch 2`,
  sum(case o.branch_id when 3 then o.qty else 0 end) as `Branch 3`,
  sum(case o.branch_id when 4 then o.qty else 0 end) as `Branch 4`,
  sum(case o.branch_id when 5 then o.qty else 0 end) as `Branch 5`,
  sum(case o.branch_id when 6 then o.qty else 0 end) as `Branch 6`,
  sum(o.qty) as `Total Qty`
from tbl_product as p
join tbl_orders as o on p.id = o.item_id
join tbl_branch as b on o.branch_id = b.id
group by p.id;

Вывод:

+-----------+----------+----------+----------+----------+----------+----------+-----------+
| item      | Branch 1 | Branch 2 | Branch 3 | Branch 4 | Branch 5 | Branch 6 | Total Qty |
+-----------+----------+----------+----------+----------+----------+----------+-----------+
| Product 1 |       12 |        0 |       67 |        1 |        0 |        0 |        80 |
| Product 2 |        3 |        0 |        0 |        0 |        1 |        0 |         4 |
| Product 3 |        1 |        4 |        0 |        0 |        0 |        0 |         5 |
| Product 4 |        2 |        0 |        5 |        0 |        0 |        0 |         7 |
| Product 5 |        0 |        0 |        0 |        0 |        0 |        3 |         3 |
+-----------+----------+----------+----------+----------+----------+----------+-----------+

Вы спросили, как сделать этот «динамический c», потому что вы получаете новые продукты и регулярно создавать новые ветки.

SQL требует, чтобы все столбцы списка выбора были фиксированы во время анализа запроса. Вы не можете создать запрос SQL, который динамически расширяет свой список столбцов на основе количества различных значений, которые он обнаруживает во время выполнения, поскольку он исследует данные.

Попытка создать запрос, расширяющий его выбор- список на основе результатов запроса похож на запись функции PHP, количество аргументов которой зависит от возвращаемого значения функции! Другими словами, это проблема курицы и яйца. Вы должны определить функцию перед ее вызовом, и определение функции зависит от результата, возвращаемого этой функцией. Это не имеет смысла.

По этой причине все запросы в стиле сводной таблицы должны выполняться в двух отдельных SQL запросах:

  1. Получить список отдельных значения, которые вы хотите преобразовать в столбцы. Например:

     select id, branch_name from tbl_branch;
    
  2. Отформатируйте результат первого запроса в списке выбора для запроса сводной таблицы, как тот, который я показал ранее.

Если вы не хотите запускать два запроса SQL, альтернативой является не , чтобы выполнить поворот в SQL. Просто выберите строки в том виде, в каком они существуют в базе данных, и напишите код для «поворота» результатов в табличное представление, как вам нравится.

0 голосов
/ 08 августа 2020

Вы можете myke Dynami c Запросы, так как вы никогда не знаете, какие ветки и продукты у вас будут в будущем

Схема (MySQL v8.0)

CREATE TABLE tbl_branch (
  `ID` INTEGER,
  `Branch_Name` VARCHAR(8)
);

INSERT INTO tbl_branch
  (`ID`, `Branch_Name`)
VALUES
  ('1', 'Branch 1'),
  ('2', 'Branch 2'),
  ('3', 'Branch3'),
  ('4', 'Branch4'),
  ('5', 'Branch5'),
  ('6', 'Branch 6');
  

CREATE TABLE tbl_product (
  `ID` INTEGER,
  `Description` VARCHAR(10)
);

INSERT INTO tbl_product
  (`ID`, `Description`)
VALUES
  ('1', 'Product 1'),
  ('2', 'Product2'),
  ('3', 'Product 3'),
  ('4', 'Product 4'),
  ('5', 'Product 5'),
  ('6', 'Product 6'),
  ('7', 'Product 7'),
  ('8', 'Product 8'),
  ('9', 'Product 9'),
  ('10', 'Product 10');

CREATE TABLE tbl_orders (
  `ID` INTEGER,
  `Branch_ID` INTEGER,
  `Item_ID` INTEGER,
  `Qty` INTEGER
);

INSERT INTO tbl_orders
  (`ID`, `Branch_ID`, `Item_ID`, `Qty`)
VALUES
  ('1', '1', '1', '12'),
  ('2', '1', '2', '3'),
  ('3', '2', '3', '4'),
  ('4', '3', '4', '5'),
  ('5', '3', '1', '67'),
  ('6', '4', '1', '1'),
  ('7', '5', '2', '1'),
  ('8', '1', '3', '1'),
  ('9', '1', '4', '2'),
  ('10', '6', '5', '3');

Запрос №1

SELECT 
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE o.`Branch_ID` WHEN "',
     o.`Branch_ID`,
      '" THEN o.`Qty` ELSE 0 END) AS `',
      b.`Branch_Name`, '`'      
    )
    ORDER BY o.`Branch_ID`
  ) 
  INTO @sql
FROM tbl_product as p
JOIN tbl_orders as o on p.ID = o.Item_ID
JOIN tbl_branch as b on o.Branch_ID = b.ID;
SET @sql = CONCAT('SELECT p.Description as item,',@sql,
                  ', SUM(o.Qty) as `Total Qty` FROM tbl_product as p
JOIN tbl_orders as o on p.ID = o.Item_ID
JOIN tbl_branch as b on o.Branch_ID = b.ID GROUP BY p.id,p.Description;');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

| item      | Branch 1 | Branch 2 | Branch3 | Branch4 | Branch5 | Branch 6 | Total Qty |
| --------- | -------- | -------- | ------- | ------- | ------- | -------- | --------- |
| Product 1 | 12       | 0        | 67      | 1       | 0       | 0        | 80        |
| Product2  | 3        | 0        | 0       | 0       | 1       | 0        | 4         |
| Product 3 | 1        | 4        | 0       | 0       | 0       | 0        | 5         |
| Product 4 | 2        | 0        | 5       | 0       | 0       | 0        | 7         |
| Product 5 | 0        | 0        | 0       | 0       | 0       | 3        | 3         |

Просмотр в DB Fiddle

...