Изменить таблицу SQL, чтобы сжать похожие строки при суммировании столбца

0

Вот вопрос, который является общей сутью того, что я пытаюсь сделать:

Суммировать значения из нескольких строк в одну строку

Однако, насколько мне известно, я ищу дополнительную функциональность, которая надолго изменит рассматриваемую таблицу, чтобы выглядеть как результат инструкции SELECT, предлагаемой в этом другом потоке.

Итак, таблица:

Sales
--------------------------------------
account    product    qty    amount
--------------------------------------
01010      bottle     10     200
01010      bottle     20     100
01010      bottle     5      10
11111      can        50     200
11111      can        25     150

... будет постоянно изменяться, чтобы выглядеть так

Sales
--------------------------------------
account    product    qty    amount
--------------------------------------
01010      bottle     35     310
11111      can        75     350

Как указано в ссылке, использование SELECT с SUM и GROUP BY может показать мне, что должна выглядеть таблица, но как я действительно применяю эти изменения в таблице продаж?

edit: этот запрос будет запускаться каждый раз, когда в систему будет добавлена новая партия продаж. Он предназначен для очистки таблицы продаж после добавления новых записей.

Альтернативный подход

Новые записи в продажах вставляются из другой таблицы, используя что-то вроде этого:

"INSERT INTO sales
    SELECT account, product, qty, amount
    FROM new_sales;"

Если есть способ позаботиться о суммировании во время предыдущего INSERT, вместо того, чтобы добавлять повторяющиеся строки в первую очередь, это также было бы приемлемым. Имейте в виду, что это решение по-прежнему необходимо будет работать для новых записей, в которых нет дубликатов строк в продажах.

EDIT: для потомков

Общий ответ, похоже, заключается в том, что мой первоначальный подход не является possible--, не создавая таблицу temp_sales с CREATE и SELECT, а затем полностью очищая продажи, а затем копируя содержимое temp_sales в очищенную таблицу продаж и сокращая temp_sales для будущего использования,

В принятом решении используется "Альтернативный подход", на который я также ссылался.

  • 0
    Например, откуда идут вставки из php?
  • 0
    Вставки копируются из другой таблицы в базе данных. Сначала я хотел скопировать данные, а затем суммировать и консолидировать только в таблице назначения, так как это будет обрабатывать случаи продаж с новыми «счетами» или «продуктами», а также суммировать продажи «кол-во» и «суммы» с существующими «счета» или «продукты». Я использую C # для форматирования и выполнения запросов. Надеемся использовать наиболее эффективные запросы, насколько это возможно, и использовать вычисления или элементы управления C # только в случае крайней необходимости.
Показать ещё 2 комментария
Теги:
database
sql-update
sum

3 ответа

0
Лучший ответ

Предполагая, что new_sales усекается после того, как продажи были обновлены, а затем начинает заполняться, вы можете использовать insert..on duplicate key..update, например

MariaDB [sandbox]> drop table if exists t,t1;
Query OK, 0 rows affected (0.20 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> create table t
    -> (account varchar(5),    product varchar(20),    qty  int default 0,  amount int default 0);
Query OK, 0 rows affected (0.16 sec)

MariaDB [sandbox]> create table t1
    -> (account varchar(5),    product varchar(20),    qty  int default 0,  amount int default 0);
Query OK, 0 rows affected (0.24 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> alter table t
    -> add unique key k1(account,product);
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> truncate table t1;
Query OK, 0 rows affected (0.23 sec)

MariaDB [sandbox]> insert into t1 values
    -> ('01010'  ,    'bottle'   ,  10   ,  200),
    -> ('01010'  ,    'bottle'   ,  20   ,  100),
    -> ('01010'  ,    'bottle'   ,  5    ,  10),
    -> ('11111'  ,    'can'      ,  50   ,  200),
    -> ('11111'  ,    'can'      ,  25   ,  150);
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> truncate table t;
Query OK, 0 rows affected (0.28 sec)

MariaDB [sandbox]> insert into t
    -> select account,product,t1qty,t1amount
    -> from
    -> (
    -> select t1.account,t1.product,sum(t1.qty) t1qty,sum(t1.amount) t1amount from t1 group by t1.account,t1.product
    -> ) s
    -> on duplicate key
    -> update qty = t.qty + t1qty, amount = t.amount + t1amount;
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> truncate table t1;
Query OK, 0 rows affected (0.32 sec)

MariaDB [sandbox]> insert into t1 values
    -> ('01010'  ,    'bottle'   ,  10   ,  200),
    -> ('01011'  ,    'bottle'   ,  20   ,  100),
    -> ('01011'  ,    'bottle'   ,  5    ,  10),
    -> ('11111'  ,    'can'      ,  50   ,  200),
    -> ('11111'  ,    'can'      ,  25   ,  150);
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> insert into t
    -> select account,product,t1qty,t1amount
    -> from
    -> (
    -> select t1.account,t1.product,sum(t1.qty) t1qty,sum(t1.amount) t1amount from t1 group by t1.account,t1.product
    -> ) s
    -> on duplicate key
    -> update qty = t.qty + t1qty, amount = t.amount + t1amount;
Query OK, 5 rows affected (0.02 sec)
Records: 3  Duplicates: 2  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+---------+---------+------+--------+
| account | product | qty  | amount |
+---------+---------+------+--------+
| 01010   | bottle  |   45 |    510 |
| 11111   | can     |  150 |    700 |
| 01011   | bottle  |   25 |    110 |
+---------+---------+------+--------+
3 rows in set (0.00 sec)

MariaDB [sandbox]>
  • 0
    Я думаю, что это в целом соответствует тому, что мне нужно. Хотя я не уверен, что окончательные значения в 't' отражают суммы того, что вы вставили в 't1' непосредственно перед этим. Например, я ожидаю, что строка «11111 | can | 150 | 700» будет читать «11111 | can | 75 | 350» --- так как это будут правильные итоги из предыдущих значений, вставленных в t1. Кажется, что значения удваиваются после сложения или просто добавляются дважды.
  • 0
    Ах, подожди. Мне жаль. Вы показали серию этих вставок, чтобы показать эффекты многократного использования. Окончательные значения являются результатом нескольких партий, полученных из t1, да?
Показать ещё 4 комментария
0

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

----------Old Таблица

CREATE TABLE yourtable (
  [state] varchar(2),
  [month] varchar(7),
  [ID] int,
  [sales] int
)
;
INSERT INTO yourtable ([state], [month], [ID], [sales])
  VALUES ('FL', 'June', 0001, '12000'),
  ('FL', 'June', 0001, '6000'),
  ('FL', 'June', 0001, '3000'),
  ('FL', 'July', 0001, '6000'),
  ('FL', 'July', 0001, '4000'),
  ('TX', 'January', 0050, '1000'),
  ('MI', 'April', 0032, '5000'),
  ('MI', 'April', 0032, '8000'),
  ('CA', 'April', 0032, '2000');

SELECT
  state,
  month,
  id,
  SUM(sales) Total
FROM yourtable
GROUP BY state,
         month,
         id;

-----Creating new table from old table

CREATE TABLE yourtable1 (
  [state] varchar(2),
  [month] varchar(7),
  [ID] int,
  [sales] int
)
;

----Inserting aggregation logic

INSERT INTO yourtable1 (state, month, id, sales)
  SELECT
    state,
    month,
    id,
    SUM(sales)
  FROM yourtable
  GROUP BY state,
           month,
           id;
-----Fetching records

SELECT
  *
FROM yourtable1;
0

Вы можете создать таблицу из оператора select.

Таким образом, вы можете сделать что-то вроде:

create table sales_sum as 
  select 
     account,
     product,
     sum(qty),
     sum(amount) 
   from 
     sales
   group by 
     account, 
     product

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

  • 0
    Значит ли это, что нет способа применить изменения к самой таблице продаж ? Этот запрос будет выполняться каждый раз, когда в систему добавляется новая партия продаж, и предназначен для поддержания чистоты таблицы продаж . Создание новой таблицы каждый раз нецелесообразно для этой цели.
  • 0
    @ Leviathan3 Я бы использовал две таблицы. Или, исходя из вашего описания, то, что вы действительно хотите, это «представление». При этом, когда таблица продаж обновляется, ваше представление (которое выглядит как таблица при использовании) автоматически обновляется. Вы можете создать представление вместо таблицы, выполнив мой запрос выше, но используйте create view sales_sum as ... вместо первой строки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню