MySQL - retrospectively add ID that AUTO_INCREMENTs - mysql
I have table with lots of rows, and there is no id column. I'd like to go back and:
add an ID column as PRIMARY KEY with AUTO_INCREMENT
more importantly, retrospectively add an ID for all the existing rows, from oldest to newest (there is an 'updatetime' column).
Any suggestions?
Let's consider the following example:
CREATE TABLE your_table (some_value int, updatetime datetime);
INSERT INTO your_table VALUES (100, '2010-08-11 12:09:00');
INSERT INTO your_table VALUES (300, '2010-08-11 12:08:00');
INSERT INTO your_table VALUES (200, '2010-08-11 12:07:00');
INSERT INTO your_table VALUES (400, '2010-08-11 12:06:00');
INSERT INTO your_table VALUES (600, '2010-08-11 12:05:00');
INSERT INTO your_table VALUES (500, '2010-08-11 12:04:00');
INSERT INTO your_table VALUES (800, '2010-08-11 12:03:00');
First we can add the id column:
ALTER TABLE your_table ADD id int unsigned;
Now the table looks like this:
SELECT * FROM your_table;
+------------+---------------------+------+
| some_value | updatetime | id |
+------------+---------------------+------+
| 100 | 2010-08-11 12:09:00 | NULL |
| 300 | 2010-08-11 12:08:00 | NULL |
| 200 | 2010-08-11 12:07:00 | NULL |
| 400 | 2010-08-11 12:06:00 | NULL |
| 600 | 2010-08-11 12:05:00 | NULL |
| 500 | 2010-08-11 12:04:00 | NULL |
| 800 | 2010-08-11 12:03:00 | NULL |
+------------+---------------------+------+
7 rows in set (0.00 sec)
Then we can UPDATE the id column with the row number when the result set is ordered by the updatetime column:
SET #row_number := 0;
UPDATE your_table
SET your_table.id = (#row_number := #row_number + 1)
ORDER BY your_table.updatetime;
Now the table looks like this:
SELECT * FROM your_table ORDER BY id;
+------------+---------------------+----+
| some_value | updatetime | id |
+------------+---------------------+----+
| 800 | 2010-08-11 12:03:00 | 1 |
| 500 | 2010-08-11 12:04:00 | 2 |
| 600 | 2010-08-11 12:05:00 | 3 |
| 400 | 2010-08-11 12:06:00 | 4 |
| 200 | 2010-08-11 12:07:00 | 5 |
| 300 | 2010-08-11 12:08:00 | 6 |
| 100 | 2010-08-11 12:09:00 | 7 |
+------------+---------------------+----+
Then we can set the id column as the primary key, and make it NOT NULL and AUTO_INCREMENT:
ALTER TABLE your_table
MODIFY id int unsigned NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (id);
This is the new description of the table:
DESCRIBE your_table;
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| some_value | int(11) | YES | | NULL | |
| updatetime | datetime | YES | | NULL | |
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
+------------+------------------+------+-----+---------+----------------+
3 rows in set (0.04 sec)
We can now try to INSERT a new row in the table to confirm that AUTO_INCREMENT is working as expected:
INSERT INTO your_table (some_value, updatetime)
VALUES (900, '2010-08-11 12:10:00');
SELECT * FROM your_table ORDER BY id;
+------------+---------------------+----+
| some_value | updatetime | id |
+------------+---------------------+----+
| 800 | 2010-08-11 12:03:00 | 1 |
| 500 | 2010-08-11 12:04:00 | 2 |
| 600 | 2010-08-11 12:05:00 | 3 |
| 400 | 2010-08-11 12:06:00 | 4 |
| 200 | 2010-08-11 12:07:00 | 5 |
| 300 | 2010-08-11 12:08:00 | 6 |
| 100 | 2010-08-11 12:09:00 | 7 |
| 900 | 2010-08-11 12:10:00 | 8 |
+------------+---------------------+----+
8 rows in set (0.00 sec)
I'm not sure if there is an easier way to tackle this, but this approach seems to do the job.
Related
tree branch from mysql
I have mysql table with schema whixh contain data to store tree structure. CREATE TABLE `treedata` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `parent_id` int(11) unsigned NOT NULL DEFAULT '0', `depth` tinyint(3) unsigned NOT NULL DEFAULT '0', `name` varchar(128) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uniquecheck` (`parent_id`,`name`) USING BTREE, KEY `depth` (`depth`) USING BTREE, KEY `parent_id` (`parent_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1 It has below data. mysql> select * from treedata; +----+-----------+-------+------+ | id | parent_id | depth | name | +----+-----------+-------+------+ | 1 | 1 | 0 | root | | 2 | 1 | 1 | b1 | | 3 | 1 | 1 | b2 | | 4 | 1 | 1 | b3 | | 5 | 2 | 2 | b1_1 | | 6 | 2 | 2 | b1_2 | | 7 | 2 | 2 | b1_3 | | 8 | 3 | 2 | b2_1 | | 9 | 3 | 2 | b2_2 | | 10 | 3 | 2 | b2_3 | | 11 | 4 | 2 | b3_1 | | 12 | 4 | 2 | b3_2 | | 13 | 4 | 2 | b3_3 | +----+-----------+-------+------+ 13 rows in set (0.00 sec) I need to select branch and its children based on depth and name, like if depth is 1 and name is b1 then it should return +----+-----------+-------+------+ | id | parent_id | depth | name | +----+-----------+-------+------+ | 2 | 1 | 1 | b1 | | 5 | 2 | 2 | b1_1 | | 6 | 2 | 2 | b1_2 | | 7 | 2 | 2 | b1_3 | +----+-----------+-------+------+ I am new to database. I tried left join it gives all children but not branch itself. mysql> select td2.* from treedata as td1 left join treedata as td2 on td1.id=td2.parent_id where td1.name='b1'; +------+-----------+-------+------+ | id | parent_id | depth | name | +------+-----------+-------+------+ | 5 | 2 | 2 | b1_1 | | 6 | 2 | 2 | b1_2 | | 7 | 2 | 2 | b1_3 | +------+-----------+-------+------+ 3 rows in set (0.00 sec) Note: I can't change database schema.
you can use like cluse for select all data which has b1 branch like this . select td2.* from treedata as td1 left join treedata as td2 on td1.id=td2.parent_id where td1.name LIKE '%b1%';
i think it may help you select * from (select * from table_name order by `depth`) products_sorted,(select #pv := 'your_node_id(string)') initialisation where (find_in_set(parent_id, #pv) or id=your_node_id) and length(#pv := concat(#pv, ',', id)) it will find all children of your starting node
How to calculate a moving average in MYSQL
I have an application that stores stock quotes into my MySQL database. I have a table called stock_history: mysql> desc stock_history; +-------------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+---------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | date | date | NO | MUL | NULL | | | close | decimal(12,5) | NO | MUL | NULL | | | dmal_3 | decimal(12,5) | YES | MUL | NULL | | +-------------------+---------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec) These are all the values in this table: mysql> select date, close, dmal_3 from stock_history order by date asc; +------------+----------+----------+ | date | close | dmal_3 | +------------+----------+----------+- | 2000-01-03 | 2.00000 | NULL | | 2000-01-04 | 4.00000 | NULL | | 2000-01-05 | 6.00000 | NULL | | 2000-01-06 | 8.00000 | NULL | | 2000-01-07 | 10.00000 | NULL | | 2000-01-10 | 12.00000 | NULL | | 2000-01-11 | 14.00000 | NULL | | 2000-01-12 | 16.00000 | NULL | | 2000-01-13 | 18.00000 | NULL | | 2000-01-14 | 20.00000 | NULL | +------------+----------+----------+- 10 rows in set (0.01 sec) I am guaranteed that there will be 0 or 1 record for each date. Can I write a single query that will insert the three-day moving average (ie: the average closing prices of that day and the two previous trading days before it) into the dmal_3 field? How? When the query is done, I want the table to look like this: mysql> select date, close, dmal_3 from stock_history order by date asc; +------------+----------+----------+ | date | close | dmal_3 | +------------+----------+----------+ | 2000-01-03 | 2.00000 | NULL | | 2000-01-04 | 4.00000 | NULL | | 2000-01-05 | 6.00000 | 4.00000 | | 2000-01-06 | 8.00000 | 6.00000 | | 2000-01-07 | 10.00000 | 8.00000 | | 2000-01-10 | 12.00000 | 10.00000 | | 2000-01-11 | 14.00000 | 12.00000 | | 2000-01-12 | 16.00000 | 14.00000 | | 2000-01-13 | 18.00000 | 16.00000 | | 2000-01-14 | 20.00000 | 18.00000 | +------------+----------+----------+ 10 rows in set (0.01 sec)
That is what I call a good challenge. My solution first creates a counter for the values and uses it as a table. From it I select everything and join with the same query as a subquery checking the position of the counter on both. Once the query works it just need an inner join with the actual table to do the update. Here it is my solution: update stock_history tb1 inner join ( select a.id, case when a.step < 3 then null else (select avg(b.close) from ( select hh.*, #stp:=#stp+1 stp from stock_history hh, (select #sum:=0, #stp:=0) x order by hh.dt limit 17823232 ) b where b.stp >= a.step-2 and b.stp <= a.step ) end dmal_3 from (select h1.*, #step:=#step+1 step from stock_history h1, (select #sum:=0, #step:=0) x order by h1.dt limit 17823232 ) a ) x on tb1.id = x.id set tb1.dmal_3 = x.dmal_3; I changed some columns names for easiness of my test. Here it is the working SQLFiddle: http://sqlfiddle.com/#!9/e7dc00/1 If you have any doubt, let me know so I can clarify! Edit The limit 17823232 clause was added there in the subqueries because I don't know which version of MySql you are in. Depending on it (>= 5.7, not sure exactly) the database optimizer will ignore the internal order by clauses making it not work the way it should. I just chose a random big number usually you can use the maximum allowed. The only column with different colunm name between your table and mine is the date one which I named dt because date is a reserved word and you should use backticks ( ` ) to use such columns, therefore I will left it as dt in above query.
A query with those fields, that are not required to get from huge fields within a table
i want a query to display few fields from a table on webpage, but there are huge number of fields in that table, but i want such type of query that except few fields and displaying all remaining fields' data on web page. Like: i have a table with 50 fields, +--------+--------+--------+----------+ +----------+ | Col1 | Col2 | Col3 | Col4 | ---- | Col50 | |---------|---------|----------|-----------| |-----------| | | | | | ---- | | | | | | | ---- | |+-------+--------+--------+----------+ +----------+ but i want to display only 48 fields on that page. then any query that except those 2 fields name(Col49 and Col50) that are not required and show remaining data. So instead of writing: SELECT Col1, Col2, Col3, Col4,...Col48 FROM table; any alternate way to writing like that SELECT *-(Col49,Col50) FROM table;
The best way to solve this is using view you can create view with those 18 columns and retrieve data form it example mysql> SELECT * FROM calls; +----+------------+---------+ | id | date | user_id | +----+------------+---------+ | 1 | 2016-06-22 | 1 | | 2 | 2016-06-22 | NULL | | 3 | 2016-06-22 | NULL | | 4 | 2016-06-23 | 2 | | 5 | 2016-06-23 | 1 | | 6 | 2016-06-23 | 1 | | 7 | 2016-06-23 | NULL | +----+------------+---------+ 7 rows in set (0.06 sec) mysql> CREATE VIEW C_VIEW AS -> SELECT id,date from calls; Query OK, 0 rows affected (0.20 sec) mysql> select * from C_VIEW; +----+------------+ | id | date | +----+------------+ | 1 | 2016-06-22 | | 2 | 2016-06-22 | | 3 | 2016-06-22 | | 4 | 2016-06-23 | | 5 | 2016-06-23 | | 6 | 2016-06-23 | | 7 | 2016-06-23 | +----+------------+ 7 rows in set (0.00 sec)
Instead of mentioning select * from ... include the column names in the query.. select col1, col2,...col18 from ..
This answer is according to you question. So add more details to your question to get more clear answer. You need to pass column names to get data for only those columns. e.g. table_name = dummy_tab col_1 | col_2 | col_3 | col_4 -------------------------------- 1 | John | 20 | abc#def -------------------------------- 2 | Doe | 21 | def#xyz ... You can do: SELECT col_1, col_2 FROM dummy_tab; This will give: col_1 | col_2 --------------- 1 | John --------------- 2 | Doe
A bit of a pain but you can reduce effort and error by interrogating information_schema and excluding the fields you don't want by name or by position for example. CREATE TABLE `dates` ( `id` INT(11) NULL DEFAULT NULL, `dte` DATE NULL DEFAULT NULL, `CalMonth` INT(11) NULL DEFAULT NULL, `CalMonthDescLong` VARCHAR(10) NULL DEFAULT NULL, `CalMonthDescShort` VARCHAR(10) NULL DEFAULT NULL, `calQtr` INT(11) NULL DEFAULT NULL ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB ; use information_schema; select concat('`',REPLACE(t.NAME,'/dates','.'), '`',replace(T.NAME,'sandbox/',''),c.NAME,'`',',') from INNODB_SYS_TABLES t join INNODB_SYS_COLUMNS c on c.TABLE_ID = t.TABLE_ID where t.NAME like ('sandbox%') and t.name like ('%dates') and pos not in(1,4) Best run from command line with the output piped to a text file.
Mysql optimization help needed
I have a table TABLE_A with 4397898 records +-------------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+---------------+------+-----+---------+----------------+ | id | bigint(11) | NO | PRI | NULL | auto_increment | | usrid | int(11) | YES | | NULL | | | grpid | int(11) | YES | | NULL | | | catid | int(11) | YES | MUL | NULL | | | folderid | int(11) | NO | MUL | 5 | | | popid | int(11) | YES | MUL | NULL | | | accid | int(11) | YES | MUL | NULL | | | contentid | bigint(11) | YES | MUL | NULL | | | priority | smallint(6) | YES | | NULL | | | rating | smallint(6) | NO | | 3 | | | fromid | int(11) | YES | | NULL | | | ctxid | varchar(255) | YES | | NULL | | | ctxmsgid | varchar(255) | YES | | NULL | | | starred | enum('Y','N') | YES | | N | | | links | enum('y','n') | YES | | n | | +-------------------+---------------+------+-----+---------+----------------+ and it is indexed as below +---------+----+--------------+-----+-------------+-----+-------------+----------+--------+------+------------+ | Table | Nu | Key_name | Seq | Column_name | Col | Cardinality | Sub_part | Packed | Null | Index_type | +---------+----+--------------+-----+-------------+-----+-------------+----------+--------+------+------------+ | TABLE_A | 0 | PRIMARY | 1 | id | A | 4617132 | NULL | NULL | | BTREE | | TABLE_A | 1 | catIndx | 1 | catid | A | 256507 | NULL | NULL | YES | BTREE | | TABLE_A | 1 | contentIndx | 1 | contentid | A | 4617132 | NULL | NULL | YES | BTREE | | TABLE_A | 1 | catIndx_2 | 1 | catid | A | 18 | NULL | NULL | YES | BTREE | | TABLE_A | 1 | catIndx_2 | 2 | popid | A | 2013 | NULL | NULL | YES | BTREE | | TABLE_A | 1 | folderidIndx | 1 | folderid | A | 13619 | NULL | NULL | | BTREE | | TABLE_A | 1 | accIndex | 1 | accid | A | 1532 | NULL | NULL | YES | BTREE | | TABLE_A | 1 | popindx | 1 | popid | A | 1532 | NULL | NULL | YES | BTREE | +---------+----+--------------+-----+-------------+-----+-------------+----------+--------+------+------------+ The following query explain SELECT intCommIndx FROM TABLE_A WHERE ( (popid IN('-1',2407 ,22 ,1203 ,1342 ,1207 ,3 ,1254 ,2663 ,1250 ,3461 ,1251 ,14 ,1174 ,120 ,2406 ,2402 ,325 ,925 ,1210 ,2280 ,1 ,1202 ,1560 ,775 ,776 ,789 ,777 ,778 ,12 ,779 ,780 ,781 ,782 ,783 ,784 ,785 ,786 ,787 ,788 ,1209 ,19 ,26 ,9 ,24 ,4 ,25 ,21 ,18 ,1309 ,967 ,1212 ,6 ,9633 ,5 ,2671 ,17 ,13 ,1211 ,749 ,752 ,747 ,750 ,748 ,9302 ,1470 ,190 ,188 ,9711 ,9710 ,9512 ,11512 ,9514 ,9515 ,9516 ,11511 ,9513 ,9316 ,9453 ,1641 ,4986 ,1639 ,1640 ,7814 ,10042 ,9452 ,11236 ,11241 ,11238 ,11239 ,11237 ,11242 ,11240 ,1711 ) OR intpop3indx = -1) AND catid = 5 ) explain SELECT id FROM TABLE_A WHERE ( (popid IN('-1',2407 ,22 ,1203 ,1342 ,1207 ,3 ,1254 ,2663 ,1250 ,3461 ,1251 ,14 ,1174 ,120 ,2406 ,2402 ,325 ,925 ,1210 ,2280 ,1 ,1202 ,1560 ,775 ,776 ,789 ,777 ,778 ,12 ,779 ,780 ,781 ,782 ,783 ,784 ,785 ,786 ,787 ,788 ,1209 ,19 ,26 ,9 ,24 ,4 ,25 ,21 ,18 ,1309 ,967 ,1212 ,6 ,9633 ,5 ,2671 ,17 ,13 ,1211 ,749 ,752 ,747 ,750 ,748 ,9302 ,1470 ,190 ,188 ,9711 ,9710 ,9512 ,11512 ,9514 ,9515 ,9516 ,11511 ,9513 ,9316 ,9453 ,1641 ,4986 ,1639 ,1640 ,7814 ,10042 ,9452 ,11236 ,11241 ,11238 ,11239 ,11237 ,11242 ,11240 ,1711 ) OR popid = -1) AND catid = 5 ) gives +----+-------------+---------+------+---------------------------+---------+---------+-------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------------------+---------+---------+-------+--------+-------------+ | 1 | SIMPLE | TABLE_A | ref | catIndx,catIndx_2,popindx | catIndx | 5 | const | 649800 | Using where | +----+-------------+---------+------+---------------------------+---------+---------+-------+--------+-------------+ How to improve the speed of the query? There are only 850 rows in the result. mysql> SELECT -> count(id) -> FROM TABLE_A -> WHERE ( -> (popid IN('-1',2407,22,1203,1342,1207,3,1254,2663,1250,3461,1251,14,1174,120,2406,2402,325,925,1210,2280,1,1202,1560,775,776,789,777,778,12,779,780,781,782,783,784,785,786,787,788,1209,19,26,9,24,4,25,21,18,1309,967,1212,6,9633,5,2671,17,13,1211,749,752,747,750,748,9302,1470,190,188,9711,9710,9512,11512,9514,9515,9516,11511,9513,9316,9453,1641,4986,1639,1640,7814,10042,9452,11236,11241,11238,11239,11237,11242,11240,1711) OR intpop3indx = -1) -> AND catid = 5 ); +--------------------+ | count(id) | +--------------------+ | 850 | +--------------------+ 1 row in set (11.22 sec) What changes can I make to get these 850 records within milliseconds?
This is the query: SELECT intCommIndx FROM TABLE_A WHERE ( (popid IN('-1',2407 ,22 ,1203 ,1342 ,1207 ,3 ,1254 ,2663 ,1250 ,3461 ,1251 ,14 ,1174 ,120 ,2406 ,2402 ,325 ,925 ,1210 ,2280 ,1 ,1202 ,1560 ,775 ,776 ,789 ,777 ,778 ,12 ,779 ,780 ,781 ,782 ,783 ,784 ,785 ,786 ,787 ,788 ,1209 ,19 ,26 ,9 ,24 ,4 ,25 ,21 ,18 ,1309 ,967 ,1212 ,6 ,9633 ,5 ,2671 ,17 ,13 ,1211 ,749 ,752 ,747 ,750 ,748 ,9302 ,1470 ,190 ,188 ,9711 ,9710 ,9512 ,11512 ,9514 ,9515 ,9516 ,11511 ,9513 ,9316 ,9453 ,1641 ,4986 ,1639 ,1640 ,7814 ,10042 ,9452 ,11236 ,11241 ,11238 ,11239 ,11237 ,11242 ,11240 ,1711 ) OR intpop3indx = -1 ) AND catid = 5 ) Queries with or can be quite hard to optimize. I would recommend creating two indexes on the table and then rewriting the query. The two indexes are intCommIndx(catid, popid, intCommIndx) and intCommIndx(catid, intpop3indx, intCommIndx). Then the new query is: SELECT intCommIndx FROM TABLE_A WHERE catid = 5 and popid IN ('-1',2407 ,22 ,1203 ,1342 ,1207 ,3 ,1254 ,2663 ,1250 ,3461 ,1251 ,14 ,1174 ,120 ,2406 ,2402 ,325 ,925 ,1210 ,2280 ,1 ,1202 ,1560 ,775 ,776 ,789 ,777 ,778 ,12 ,779 ,780 ,781 ,782 ,783 ,784 ,785 ,786 ,787 ,788 ,1209 ,19 ,26 ,9 ,24 ,4 ,25 ,21 ,18 ,1309 ,967 ,1212 ,6 ,9633 ,5 ,2671 ,17 ,13 ,1211 ,749 ,752 ,747 ,750 ,748 ,9302 ,1470 ,190 ,188 ,9711 ,9710 ,9512 ,11512 ,9514 ,9515 ,9516 ,11511 ,9513 ,9316 ,9453 ,1641 ,4986 ,1639 ,1640 ,7814 ,10042 ,9452 ,11236 ,11241 ,11238 ,11239 ,11237 ,11242 ,11240 ,1711 ) UNION SELECT intCommIndx FROM TABLE_A WHERE catid = 5 and intpop3indx = -1; This will allow each subquery to be satisfied only using the indexes.
I would try to put the last conditions in first position. So when one of them isn't verified, we pass directly to the other row : catid = 5 AND (intpop3indx = -1 OR popid IN (...)) So when catid != 5, the query passes directly to the other row. (Even if catid = 5 AND intpop3indx = -1)
Your query is selecting column intCommIndx from the table, but that column does not appear as one of the table columns. The quick answer is to create a "covering index" e.g. ... ON TABLE_A (catid, intpop3indx, popid, intCommIndx) EXPLAIN output should show "Using index" in the Extra column, which means the query is satisfied entirely from the index without a need to look up pages from the table.
Automatically Update 2 Table or Multiple in Mysql
I have problem I want to ask, how to change the data that has been entered into the table rekap_nilai. which is where the table is rekapan rekap_nilai total of table nilai_student. I enter a table B based on trigger mysql> select * from nilai_student; +----+-------+------+-------+ | id | name | idmp | nilai | +----+-------+------+-------+ | 1 | Udin | 1 | 80 | | 2 | Udin | 2 | 60 | | 3 | Mamat | 1 | 75 | +----+-------+------+-------+ table rekap_nilai mysql> desc rekap_nilai; +-----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | idstudent | int(11) | YES | | NULL | | | name | varchar(100) | YES | | NULL | | | nilai | double | YES | | NULL | | +-----------+--------------+------+-----+---------+----------------+ mysql> select * from rekap_nilai; +----+-----------+-------+-------+ | id | idstudent | name | nilai | +----+-----------+-------+-------+ | 1 | 1 | Udin | 140 | | 2 | 2 | Mamat | 75 | +----+-----------+-------+-------+ 2 rows in set (0.00 sec) What if there was a remedial student conduct and when update table nilai_student in column nilai, automatically in table rekap_nilai in column nilai example now name 'Udin' have nilai 60 in id 2, and he want remedial. when he was remedial, I want to update he's nilai = 70 , and then in table rekap_nilai. udin automatically update to nilai = 150
You can write a trigger which gets executed on update of table nilai_student , some thing like below Delimiter /// create trigger update_rekap_nilai after update on nilai_student for each row begin update recap_nilai set nilai = nilai - Old.nilai + New.nilai where name=Old.name end; /// Delimiter ; Hope this helps !!