为多行创建触发器

时间:2019-03-08 18:20:47

标签: mysql sql

我有表#include <stdio.h> #include <stdlib.h> #define BLOCKS 20 int *memory[BLOCKS]; int main( void ) { int seg; FILE *stream = fopen( “file.csv”, “r” ); if ( !stream ) // print error and exit printf( “Please enter a number: “); if ( scanf( “%d”, &seg ) != 1 ) // print error and exit for ( size_t b = 0; b < BLOCKS; b++ ) { /** * Allocate memory for a block (row) */ memory[b] = malloc( sizeof *b * seg ); if ( !memory[b] ) // print error and exit /** * Read that row from the file - since it has * a .csv extension, I am assuming it is * comma-delimited. Note that malloc is not * required to initialize memory to any specific * value - the initial value of each memory[b][s] * is indeterminate. */ for ( size_t s; s < seg; s++ ) if ( fscanf( stream, “%d%*c”, &memory[b][s] )) != 1 ) // print error and exit } fclose( stream ); /** * Do stuff with memory here */ /** * After you’re done with memory, free it */ for ( size_t b = 0; b < BLOCKS; b++ ) free( memory[b] ); return EXIT_SUCCESS; } users。在orders中的每个UPDATE行之后。我要更新orders表中的DATA,即concat(OLD.DATA +已更新的ID)。

users

例如:

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;

我该怎么办?

2 个答案:

答案 0 :(得分:0)

我认为您犯的错误与不久前一样,即将数组/对象存储在列中。

在您的情况下,我建议使用以下表格:

用户

"V"

订单

+-----------+-----------+
|    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

这将返回:

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 5个以上的表进入一个视图,有时您可能需要两次JOIN同一张表。

我希望这会有所帮助,尽管它不能完全回答您的问题!

答案 1 :(得分:0)

在插入(或更新)ORDERS表之后更新USERS表可能是一个坏主意。避免两次存储数据。在您的情况下:您始终可以通过查询ORDERS表获得用户的所有“订单ID”。因此,您无需再次将它们存储在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