Создать триггер для нескольких строк - PullRequest
0 голосов
/ 08 марта 2019

У меня есть таблица users И orders.После каждой строки ОБНОВЛЕНИЕ в orders.Я хочу обновить DATA в users таблице, а именно concat (OLD.DATA + ID, который был обновлен).

Table 'users'.

ID  NAME    DATA
1   John    1|2
2   Michael 3|4
3   Someone 5

Table 'orders'.

ID  USER    CONTENT
1   1       ---
2   1       ---
3   2       ---
4   2       ---
5   3       ---

Например:

SELECT `data` from `users` where `id` = 2; // Result: 3|4
UPDATE `orders` SET '...' WHERE `id` > 0;
**NEXT LOOP**
UPDATE `users` SET `data` = concat(OLD.data, ID.rowUpdated) WHERE `user` = 1;
UPDATE `users` SET `data` = concat(OLD.data, ID.rowUpdated) WHERE `user` = 1;
UPDATE `users` SET `data` = concat(OLD.data, ID.rowUpdated) WHERE `user` = 2;
UPDATE `users` SET `data` = concat(OLD.data, ID.rowUpdated) WHERE `user` = 2;
UPDATE `users` SET `data` = concat(OLD.data, ID.rowUpdated) WHERE `user` = 3;

Результат:

SELECT data from users where id = 1; // Result: 1|2|1|2
SELECT data from users where id = 2; // Result: 3|4|3|4
SELECT data from users where id = 3; // Result: 5|5

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 09 марта 2019

Возможно, плохая идея обновить таблицу USERS после вставки (или обновления) таблицы ORDERS. Избегайте хранения данных дважды. В вашем случае: вы всегда можете получить все «идентификаторы заказа» для пользователя, запросив таблицу ORDERS. Таким образом, вам не нужно хранить их в таблице USERS (снова). Пример (протестирован с MySQL 8.0, см. dbfiddle ):

Таблицы и данные

create table users( id integer primary key, name varchar(30) ) ;

insert into users( id, name ) values
(1, 'John'),(2, 'Michael'),(3, 'Someone') ;

create table orders( 
  id integer primary key
, userid integer
, content varchar(3) references users (id) 
);

insert into orders ( id, userid, content ) values
 (101, 1, '---'),(102, 1, '---')
,(103, 2, '---'),(104, 2, '---'),(105, 3, '---') ;

Может быть, VIEW - аналогичный приведенному ниже - поможет. (Преимущество: вам не нужны дополнительные столбцы или таблицы.)

-- View
-- Inner SELECT: group order ids per user (table ORDERS).
-- Outer SELECT: fetch the user name (table USERS)
create or replace view userorders ( 
  userid, username, userdata 
)
as
select
  U.id, U.name, O.orders_
from ( 
  select 
    userid
  , group_concat( id order by id separator '|' )  as orders_
  from orders
  group by userid
) O join users U on O.userid = U.id ;

Как только представление будет на месте, вы можете просто ВЫБРАТЬ из него, и вы всегда получите текущие «пользовательские данные», например,

select * from userorders ;

-- result 
userid  username    userdata
1       John        101|102
2       Michael     103|104
3       Someone     105


-- add some more orders
insert into orders ( id, userid, content ) values 
 (1000, 1, '***'),(4000, 1, '***'),(7000, 1, '***')
,(2000, 2, ':::'),(5000, 2, ':::'),(8000, 2, ':::')
,(3000, 3, '@@@'),(6000, 3, '@@@'),(9000, 3, '@@@') ;


select * from userorders ;

-- result
userid  username  userdata
1       John      101|102|1000|4000|7000
2       Michael   103|104|2000|5000|8000
3       Someone   105|3000|6000|9000
0 голосов
/ 09 марта 2019

Я думаю, что вы делаете ту же ошибку, которую я сделал не так давно, то есть сохраняете массив / объект в столбце.

Я бы рекомендовал использовать в вашем сценарии следующие таблицы:

Пользователи

+-----------+-----------+
|    id     | user_name |
+-----------+-----------+
|     1     |   John    |
+-----------+-----------+
|     2     |  Michael  | 
+-----------+-----------+

Заказы

+-----------+-----------+------------+
|    id     | user_id   |date_ordered|   
+-----------+-----------+------------+
|     1     |     1     | 2019-03-05 |
+-----------+-----------+------------+
|     2     |     2     | 2019-03-05 |
+-----------+-----------+------------+

Где user_id - внешний ключ для users

продажа

+-----------+-----------+------------+------------+------------+
|    id     | order_id  |  item_sku  |    qty     |   price    |
+-----------+-----------+------------+------------+------------+
|     1     |     1     |    1001    |     1      |   2.50     |
+-----------+-----------+------------+------------+------------+
|     2     |     1     |    1002    |     2      |   3.00     |
+-----------+-----------+------------+------------+------------+
|     3     |     2     |    1001    |     2      |   2.00     |
+-----------+-----------+------------+------------+------------+

где order_id - внешний ключ для orders

Теперь о запутанной части. Вам нужно будет использовать серию JOIN s для доступа к соответствующим данным для каждого пользователя.

SELECT 
t3.id AS user_id,
t3.user_name,
t1.id AS order_id,
t1.date_ordered,
SUM((t2.price * t2.qty)) AS order_total   
FROM orders t1
JOIN sales t2 ON (t2.order_id = t1.id)
LEFT JOIN users t3 ON (t1.user_id = t3.id)
WHERE user_id=1
GROUP BY order_id;

Это вернет:

+-----------+--------------+------------+------------+--------------+
|  user_id  |  user_name   |  order_id  |date_ordered|  order_total |   
+-----------+--------------+------------+------------+--------------+
|     1     |    John      |      1     | 2019-03-05 |     8.50     |
+-----------+--------------+------------+------------+--------------+

Этот тип операторов JOIN должен встречаться практически в любом проекте, использующем реляционную базу данных (то есть, если вы правильно проектируете свою БД). Обычно я создаю view для каждого из этих сложных запросов, к которым затем можно получить доступ с помощью простого SELECT * FROM orders_view

Например:

CREATE 
    ALGORITHM = UNDEFINED 
    DEFINER = `root`@`localhost` 
    SQL SECURITY DEFINER
VIEW orders_view AS (

  SELECT 
  t3.id AS user_id,
  t3.user_name,
  t1.id AS order_id,
  t1.date_ordered,
  SUM((t2.price * t2.qty)) AS order_total   
  FROM orders t1
  JOIN sales t2 ON (t2.order_id = t1.id)
  LEFT JOIN users t3 ON (t1.user_id = t3.id)
  GROUP BY order_id
)

К этому можно получить доступ:

SELECT * FROM orders_view WHERE user_id=1;

Что выдаст те же результаты, что и запрос выше.

В зависимости от ваших потребностей, вам, вероятно, потребуется добавить еще несколько таблиц (addresses, products и т. Д.) И еще несколько строк в каждую из этих таблиц. Очень часто вы обнаружите, что вам нужно JOIN 5+ таблиц в представлении, а иногда вам может понадобиться JOIN одна и та же таблица дважды.

Надеюсь, это поможет, несмотря на то, что он не совсем отвечает на ваш вопрос!

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