i am new to this and want some help.i have table with name "abc" with following entries
+------+--------+------+
| Id | Name | City |
+------+--------+------+
| 101 | john | abc |
| 102 | Miller | cbz |
+------+--------+------+
and another table "xyz"
+------+--------+------+
| Id | Name | City |
+------+--------+------+
| 102 | Miller | cbz |
+------+--------+------+
i applied trigger on table "abc" which will update the table "xyz" with recently inserted values and will delete all previous entries...
for example, when i fire insert query on "abc" table i get ,"abc" as follow
insert into abc Values(103,'Joseph','xyz');
i get output for table "abc" as,
+------+--------+------+
| Id | Name | City |
+------+--------+------+
| 101 | john | abc |
| 102 | Miller | cbz |
| 103 | Joseph | xyz |
+------+--------+------+
and table "xyz" as,
+------+--------+------+
| Id | Name | City |
+------+--------+------+
| 103 | Joseph | xyz |
+------+--------+------+
now my question is how to acheive this using only one table(i dont want to use two table as this is not my requirement).
like following ..
insert into xyz values(104,'Ridhit','pqr');
+------+--------+------+
| Id | Name | City |
+------+--------+------+
| 104 | Ridhit | pqr |
+------+--------+------+
Please help.Trigger i used is
DELIMITER !!
create trigger OnlyOne BEFORE INSERT on abc
for each row
BEGIN
DECLARE a1 INT;
Select count(1) INTO a1 from xyz;
IF a1>0 THEN
delete from xyz limit 1;
insert into xyz(Id,Name,City) values (new.Id,new.Name,new.City);
ELSE
insert into xyz(Id,Name,City) values (new.Id,new.Name,new.City);
END IF;
END;
!!
DELIMITER ;
Do this on application level, but you better make sure you use transactions. You probably don't want to have an empty table, when the operation crashes in the middle.
You may also consider to have following approach.
Instead of deleting/updating whenever an insert occurs, add a column like created with default value of current timestamp to your table so that it looks something like this:
CREATE TABLE abc(
id int auto_increment primary key,
name varchar(50),
city varchar(50),
created timestamp default current_timestamp
);
To get the latest entry you just do
SELECT * FROM abc ORDER BY created DESC LIMIT 1;
Or you put this in a view
CREATE VIEW just_latest_entry_from_abc AS
SELECT * FROM abc ORDER BY created DESC LIMIT 1;
Then you just do
SELECT * FROM just_latest_entry_from_abc;
When table size matters, create a cronjob or a scheduled event to delete older entries on a regular basis.
Related
Pre-Information
I've table called Test:
-- Table Creation
CREATE TABLE Test(
id integer,
title varchar (100)
);
-- Insertion
INSERT INTO Test Values
(1, "Hi"),
(2, 'Hello'),
(2, "Hellew"),
(3, "World"),
(3,"Wordy");
Test Table
| Id | title |
|----|--------|
| 1 | Hi |
| 2 | Hello |
| 2 | Hellew |
| 3 | World |
| 3 | Wordy |
Process
I want to delete the duplicates id
Based on the priority
The Problem
This is the output Error I get
ERROR 1093 (HY000) at line 5: You can't specify target table 'Test' for update in FROM clause
Required OUTPUT
| Id | title |
|----|--------|
| 1 | Hi |
| 2 | Hello |
| 3 | World |
Thanks,
You have not clearly mentioned what is the "priority" here. But looking at the output example, I am assuming that the priority is to keep those strings which are greater than the others with similar id. Here is my code:
delete a.* from Test a join Test b
on a.id = b.id where a.title < b.title;
select * from Test;
Reference
MySQL: ALIASES
+----+------------+------------+------------+----------+
| id | phone_no | join_date | city | blood_gp |
+----+------------+------------+------------+----------+
| 1 | 80077672xx | 1997-07-19 | Delhi | NULL |
| 2 | 80077642xx | 1998-07-19 | New Delhi | NULL |
| 3 | 80477642xx | 1999-07-19 | Mumbai | NULL |
| 4 | 80077654xx | 1997-05-31 | Kolkata | NULL |
+----+------------+------------+------------+----------+
I want to enter all the blood groups at once . Is there a way to do so ?
you can use single query with select and update
UPDATE table1 , (SELECT * FROM table2 where 1) src
SET table1.blood_gp = src.filed2 where 1 ;
if you want to insert multiple row data using single query then use this code
INSERT INTO yourtable (x,y,z) VALUES (a1,a2,a3), (b1,b2,b3);
or if you want to update one column value all filed then use this code
update yourtable set blood_gp = 'yourvalue' where 1;
if any problem then inform me
Just make an update query without where clause.
update table set blood_gp = 'value'
That's generalize query.
I'm currently working with a client that wants their database to duplicate info into a second table in a different format when it is initially inserted.
Basically like the following:
Table 1
| ID | NAME | EMAIL | password |
--------------------------------------
| 1 | david | x#x.co | asx234 |
| 2 | anthony | y#x.co | 24gss3 |
| 3 | jillian | z#x.co | hdfg5d |
Every time a row gets inserted into table 1 they also want to take that information from table 1 and add it to Table 2
Table 2
| ID | NAME | EMAIL | password | signature | level | lastenter | register_date |
-----------------------------------------------------------------------------------------------
| 1 | david | x#x.co | asx234 | text | 3 | 0000-00-00 | Date of insert |
| 2 | anthony | y#x.co | 24gss3 | text | 3 | 0000-00-00 | Date of insert |
| 3 | jillian | z#x.co | hdfg5d | text | 3 | 0000-00-00 | Date of insert |
How do I set up a trigger to insert the data into Table 2 whenever a row is inserted into table 1?
Thanks!
Some thoughts below, but the trigger would look something like this:
DELIMITER $$
DROP TRIGGER IF EXISTS trgMyNewTrigger $$
CREATE TRIGGER trgMyNewTrigger AFTER INSERT ON Table1
FOR EACH ROW
BEGIN
INSERT into Table2 (ID,NAME,EMAIL,`password`,signature,`level`,lastenter,register_date) VALUES (
new.ID, new.NAME, new.EMAIL, new.password, 'text', 3, '0000-00-00', CURDATE() );
END $$
DELIMITER ;
This is not a great solution. Triggers in general can cause some nasty issues and limit your capabilities down the road. It would be better to reconsider the design of the table to be inclusive of the data you need, have the application perform the extra step or use some sort of ETL process to get the data at set intervals.
I will all assume the clear text passwords are for the example.
I want to select data from a mysql-view which collects and joins data from "federated"-tables.
This data should be inserted into a table which looks very similar to the view.
an example would be:
table where data needs to be inserted or updated:
insertTable
+----+-----------+------+-------------+
| id | foreignId | data | foreignData |
+----+-----------+------+-------------+
| 1 | a | 111 | aaa |
| 2 | b | 222 | bbb |
+----+-----------+------+-------------+
the view where the data comes from:
dataView
+-----------+-------------+
| foreignId | foreignData |
+-----------+-------------+
| a | AAA |
| b | BBB |
| c | CCC |
+-----------+-------------+
insertTable
+----+-----------+------+-------------+
| id | foreignId | data | foreignData |
+----+-----------+------+-------------+
| 1 | a | 111 | AAA |
| 2 | b | 222 | BBB |
| 3 | b | | CCC |
+----+-----------+------+-------------+
and at this point i think i need a stored procedure which does following written in pseudo code
$result = SELECT * FROM dataView;
foreach $result as $row {
if(SELECT COUNT(*) FROM inserTable WHERE foreignId=$row[foreignId]>0)
UPDATE insertView SET foreignData = $row[foreignData] WHERE foreignId=$row[foreignId];
else
INSERT INTO insertView (id, foreignId, foreignData) VALUES (null,$row[foreignId],$row[foreignData];
}
You can use REPLACE query.
REPLACE INTO insertView (id, foreignId, foreignData) VALUES (null,$row[foreignId],$row[foreignData];
From mysql documentation
REPLACE works exactly like INSERT, except that if an old row in the
table has the same value as a new row for a PRIMARY KEY or a UNIQUE
index, the old row is deleted before the new row is inserted. See
Section 13.2.5, “INSERT Syntax”.
PRIMARY KEY or a UNIQUE index not specified it will insert a new row.
So no need to SELECT checking.
The magic which is ideal for this problem was ON DUPLICATE KEY UPDATE
In my example the solution would look like this:
INSERT INTO insertTable
(
`foreignId`,
`foreignData`
)
SELECT
`dataView`.`foreignId`,
`dataView`.`foreignData`
FROM
`dataView`
ON DUPLICATE KEY UPDATE
`foreignId` = `dataView`.`foreignId`,
`foreignData` = `dataView`.`foreignData`;
I've come across this problem numerous times but haven't found a "MySQL way" to solve the issue as such - I have a database that contains users and reports. Each report has an id which I display as a report number to my users.
The main complaint is that users are confused as to why reports have gone missing from their system. This is not actually the case. It is actually that they are recognizing a gap between their IDs and assume that these are missing reports, when in actual fact, it is simply becasue another user has filled in this auto-incrementing gap.
I need to know if there is a way to do this in MySQL:
Is it possible that I can have a second auto-increment field called report_number which is based on a user_id field which has a different set of auto-increments per user?
e.g.
|------|---------|---------------|
| id | user_id | report_number |
|------|---------|---------------|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 1 | 4 |
| 6 | 1 | 5 |
| 7 | 2 | 2 |
| 8 | 3 | 1 |
| 9 | 3 | 2 |
|------|---------|---------------|
I am using InnoDB for this as it is quite heavily weighted with foreign-keys. It appears to complain when I add a second auto increment field, but I wasn't sure if there was a different way to do this?
MyISAM supports the second column with auto increment, but InnoDB doesn't.
For InnoDB you might create a trigger BEFORE INSERT to get the max value of the reportid and add one to the value.
DELIMITER $$
CREATE TRIGGER report_trigger
BEFORE INSERT ON reports
FOR EACH ROW BEGIN
SET NEW.`report_id` = (SELECT MAX(report_id) + 1 FROM reports WHERE user_id = NEW.user_id);
END $$
DELIMITER ;
If you can use MyISAM instead, in the documentation of MySQL page there is an example:
http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Which returns:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
Right one with IFNULL:
DELIMITER $$
CREATE TRIGGER salons_trigger
BEFORE INSERT ON salon
FOR EACH ROW BEGIN
SET NEW.salon_id = IFNULL((SELECT MAX(salon_id) + 1 FROM salon WHERE owner = NEW.owner), 1);
END $$
DELIMITER ;
I think mysql doesnt support two auto_increment columns. you can create report number using information schema.
select NULL from information_schema.columns
MySQl does not support two auto incremented fields, if you need then create another table, set the other field which you want to be as auto incremented and you must set up a relationship with these two tables.