mysql (copy) insert into from select and add one alias column - mysql

I have 2 tables
test_table:
id data_text
1 *some text*
undo_test_table:
id data_text modification_date
.
CREATE TRIGGER undo_trigger BEFORE UPDATE
ON test_table
FOR EACH ROW
INSERT INTO undo_test_table SELECT *,NOW() AS modification_date
FROM test_table
WHERE id = NEW.id
What I try with that, is if one column on first table is modified then the trigger (undo_trigger) is fired and copy entire row to another table (undo_test_table )
But in the second table (undo_test_table ) I have one more column (modification_date)
The problem:
The above example working good but I don't know how to make that working if I change the (modification_date) column at first place instead as last place in (undo_test_table)
like this:
undo_test_table:
modification_date id data_text
I have tried :
SELECT NOW() AS modification_date,* FROM test_table ...
instead
SELECT *,NOW() AS modification_date FROM test_table ...
But got sintax error.
I think i need some like an UNION but I don't know how I can use NOW() AS modification_date in one UNION

You need to qualify the * with the table's name:
SELECT NOW() AS modification_date, t.*
-- Here ---------------------------^
FROM test_table
-- etc...

Related

Automatically add days to a column based on other table columns

I have a table A which has column NoOfDays, and another table B which has a column MyDate of type datetime and it is set to Default as "CURRENT_TIMESTAMP".
Now in table B, I want to add a new column (called ValidDate), which should AUTOMATICALLY store the sum value of (B.MyDate + A.NoOfDays)
For example, if B.MyDate has value of "2022-07-25 04:50:26" and A.NoOfDays has value of "60", then B.ValidDate should get the value of "2022-09-23 04:50:26"
What is the way in MySQL to set this new column value to store this summed value automatically.
Checked for existing threads, but found only this one which does not offer a solution to store, but to create a view output only.
MySQL - Add number of days to date in 3rd column automatically
For existing rows in table_b , use an update statement like UPDATE table_b set ValidDate=date_add(MyDate , interval + (select NoOfDays from table_a) day);
For new inserts, we can use a trigger to handle that. Here is the complete script written and tested in workbench:
create table table_a (NoOfDays int);
create table table_b(MyDate timestamp,ValidDate datetime);
insert table_a values(60);
DELIMITER //
drop trigger if exists auto_sum //
create trigger auto_sum before insert on table_b for each row begin
set new.ValidDate=date_add(new.MyDate , interval + (select NoOfDays from table_a) day);
end //
delimiter ;
insert into table_b (MyDate) values (default); -- The value of ValidDate is calculated in the trigger,so we only need to specify the value for MyDate.
Please try this:
CREATE TABLE TableA (NoOfDays INT);
INSERT INTO TableA VALUES(60);
CREATE TABLE TableB(MyDate DATETIME DEFAULT CURRENT_TIMESTAMP);
INSERT INTO TableB VALUES('2022-07-25 04:50:26');
ALTER TABLE TableB
ADD ValidDate DATETIME;
UPDATE TableB
SET ValidDate = date_add(MyDate, INTERVAL (SELECT NoOfDays FROM TableA) DAY);
If we test the result :
SELECT * FROM TableB;

mysql insert value if it doesn't exist

I'm trying to insert an ingredient to an ingredients table if it doesn't exist.
I'm using the following syntax:
INSERT INTO ingredient(Name)
(
SELECT 'ingName' FROM dummytable WHERE
(SELECT count(*) FROM ingredient WHERE Name = 'ingName')=0)
This does not seem to work (0 rows affected), even though the SELECT query seem to return the desired result (an entry which contains "ingName").
The "ingredient" table has 2 columns: Name, id (id is auto incremented)
Thanks,
Li
Its better to add unique index on the name column:
ALTER TABLE `ingredient` ADD UNIQUE(`Name`)
After doing that you can use INSERT IGNORE:
INSERT IGNORE INTO `ingredient` ... /* anything */
That's because your inner query SELECT count(*) FROM ingredient WHERE Name = 'ingName' is returning a value > 0 and hence the upper query SELECT 'ingName' FROM dummytable WHERE is not selecting any rows and so no insert is happening.
I tried the same with a test table having 2 column name|value and it did worked fine
INSERT INTO test1(name) (
SELECT 'name' FROM test2 WHERE
(
SELECT count(*) FROM test2 WHERE name = 'bilboa'
)
=0
)
Inserted 2 rows with value name cause that's what I am selecting in select query and my test table 2 rows.

Creating a table on the basis of a field

I have a MySql table which has about 100k rows. there is one field say id which contains numbers from 1-35. all these records fall in this range of id i.e. all these records have value of id column between 1-35.
Now i want to create another table which will have one row of each id. i.e the new table should have 35 rows only.
How to go about it ?
create table new_table (id int);
insert into new_table
select distinct id from big_table;
Edit:
You can create the new_table by outputting the big_table create script and changing the name.
SHOW CREATE TABLE big_table;
/* modify the name of the output and execute */
insert into new_table
select * from big_table group by id
You have a table with 100.000 rows, and you want a new table with 35 rows. What values do you want for the remaining columns?
If the answer is: doesn't matter, this works:
CREATE TABLE newTable
SELECT * FROM yourTable
GROUP BY ID;
If you only want the IDs,
CREATE TABLE newTable
SELECT DISTINCT ID FROM yourTable;
You can copy data from one table to another even difference database(Schema) as following
INSERT INTO [DestDatabase].[DestTablName]
SELECT [ColumnName] FROM [SourceDatabase].[SourceTablName];
So, you can use two way:
1:
INSERT INTO tbl_New
SELECT DISTINCT id from tbl_Original;
2:
INSERT INTO tbl_New
SELECT id from tbl_Original GROUP BY id;

mySQL: 1)single column name aliased 2) adding virtual column

Two questions:
1)
There are several tables that are used as an archive for other tables.
To do so, there is a
INSERT INTO data_archive_table (SELECT * FROM data_table)
The problem is that the data_table.id should be kept as data_archive_table.old_id.
Is there a way to write a query that will look like: SELECT *, id AS old_id FROM data_table, while the results columns will have ONLY the old_data column, and NOT the original id column?
Using all column names is the only option I see, but I prefer to avoid it.
2)
I want to add a virtual column named deleted_time to the insertion query, that will hold the current time.
Can it be done? if so - how ?(tutorials will be great)
Try this:
1.) You can use something like this query:
INSERT INTO data_archive_table
SELECT id AS old_id -- be sure that data_archive_table has column oldID
,... -- You need to specify the names of the columns
FROM data_table
WHERE id = 'IDHERE' -- If you want to have condition.
2.) For this, you can add the value directly in you select statement
INSERT INTO `tableName`
SELECT colA,
colB,
, ...
, NOW() as deleted_time -- NOW() is a function in MySQL
FROM `sourceTable`
WHERE colA = 'IDHERE' -- If you want to have condition.
NOW() in MySQL

Cannot insert row when table is empty in MySql

I wanna insert a row when the name not exists in the table.
When the table is empty,it cannot insert anything, anyone can help me?
Here is my code:
INSERT INTO `ediftpdb`.`users`(
name
,passwd
,vendor
)
SELECT
'L001'
,'12345678a'
,'MKTPLS'
FROM `ediftpdb`.`users`
WHERE NOT EXISTS (SELECT * FROM `ediftpdb`.`users` WHERE name='L001' AND vendor = 'MKTPLS' ) LIMIT 1;
P.S.
I found a funny stuff, when ediftpdb.users is empty, code like below returns nothing.
SELECT
'L001'
,'12345678a'
,'MKTPLS'
FROM `ediftpdb`.`users`
The better way to do this is to create a unique multi-part index on name and vendor columns:
CREATE UNIQUE INDEX name_vendor ON ediftpdb.users( name, vendor )
Then:
INSERT IGNORE INTO ediftpdb.users ( name, passwd, vendor )
VALUES ( 'L001', '12345678a', 'MKTPLS' )
will do exactly what you want to do.
As #Martin Smith pointed, when the table ediftpdb.users is empty the FROM ediftpdb.users
results in no rows. If it had 100 rows, then your statement would try to INSERT 100 (identical) records into the table.
Try this:
INSERT INTO
...
SELECT
'L001'
,'12345678a'
,'MKTPLS'
FROM (SELECT 1) AS dummy
WHERE NOT EXISTS ...