I am working with a database table that stores, among other things, an AssociateID field and a DocumentName field. The table is used to keep records of which associates are missing which documents.
I am trying to write a stored procedure that will remove a row for 'Restrictive Covenant Letters' if an entry for 'Termination Statement' cannot be found for the same associate. Below is the body of what I have so far:
DELETE from tbl_HR_Auditing_Reports
WHERE DocumentName = 'Restrictive Covenant Letters'
AND NOT EXISTS
(
SELECT TS.AssociateID
FROM
(SELECT AssociateID FROM tbl_HR_Auditing_Reports WHERE DocumentName = 'Termination Statement (*)') TS,
(SELECT AssociateID FROM tbl_HR_Auditing_Reports WHERE DocumentName = 'Restrictive Covenant Letters') RCL
WHERE TS.AssociateID = RCL.AssociateID
)
I think I am close, but sql isn't really my forte. If anyone could possibly help, I would really appreciate it!
According to the MySQL manual:
Currently, you cannot delete from a table and select from the same table in a subquery.
To get around this you can use a temporary table, inserting the relevant rows into the temporary table, then referencing it in the delete statement.
CREATE TEMPORARY TABLE tmp (AssociateID INT);
INSERT INTO tmp (AssociateID)
SELECT AssociateID
FROM tbl_HR_Auditing_Reports
WHERE DocumentName = 'Termination Statement (*)';
DELETE
FROM tbl_HR_Auditing_Reports
WHERE DocumentName = 'Restrictive Covenant Letters'
AND NOT EXISTS
( SELECT 1
FROM tmp
WHERE tmp.AssociateID = tbl_HR_Auditing_Reports.AssociateID
)
Example on SQL Fiddle
Related
I have a table with many columns in SQL Server and I have move part of data into MySQL. I made a view or function on the table in SQL Server and these two databases must be synced once a day through job. Because the data of this view may change every day.
View return a table with 3 columns: (char, varchar, varchar) that none of them are unique or primary key.
My solution is:
create a job
execute view on SQL Server
return result of view
create temp table with 3 column in MySQL
move result view from SQL Server to temp table
move records from temp table to new table one by one if not exist before
delete temp table
To transfer without using the temp table, I wanted to use below type of query but could not find the correct query. That's why I used the temp table:
insert into new_table
values (array of records) where record if not exist in new table.
And for the solution I mentioned above, I used the following query:
insert into new_table
select *
from temp_table
where not exist new_table.column = temp_table.column
Do you have a better suggestion that new records can be fetch and added to previous records?
It should look more like this:
insert into new_table
select *
from temp_table
where not exists (
select 1
from new_table
where new_table.column = temp_table.column
)
or maybe this:
insert into new_table
select *
from temp_table
where not exists (
select 1
from new_table
where new_table.column = temp_table.column
and new_table.column2 = temp_table.column2
and new_table.column3 = temp_table.column3
)
I want to update a MySQL table from matlab in bulk. The current logic that I use iterates over the array and inserts it one-by-one which takes way too long.
Here is my current implementation-
function update_table(customer_id_list, cluster_id_list, write_conn)
num_customers = size(customer_id_list, 1);
for idx=1:num_customers+1
customer_id = customer_id_list(idx);
cluster_id = cluster_id_list(idx);
sql = strcat(sql, 'UPDATE table SET cluster_id = ', num2str(cluster_id), ' WHERE customer_id = ', num2str(customer_id));
exec(write_conn, sql);
end
end
Tried to look for documentation to do bulk update/insert, but haven't found anything yet.
Do an "upjoin" using a temporary table.
Build your update specification as a Matlab table array with all the cluster_id and customer_id pairs that specify the new values.
Create a SQL temporary table that contains columns for the key columns you'll be matching on and the columns to update.
CREATE TEMPORARY TABLE my_temp_table SELECT customer_id, cluster_id FROM table WHERE 1 = 0
Batch-insert your update specification data from Matlab into the temporary table using Matlab Database Toolbox's datainsert or sqlwrite.
Update the target table en masse by joining it to the temp table: UPDATE table SET targ.cluster_id = upd.cluster_id FROM table targ INNER JOIN my_temp_table upd ON targ.customer_id = upd.customer_id.
Drop the temp table.
Boom. If you're going to do this a lot, wrap it up in a generic upjoin() function.
See the Matlab documentation for datainsert and sqlwrite. Do not use fastinsert; despite its name, it is much slower than datainsert and sqlwrite.
I have a table Provision with this structure:
ONT_ID varchar(12) PK
neID set('7360-1','7360-2','7360-3','5000-1','5000-2') not null
and some other crap
I have loaded a temporary table called tempTable that has the same structure and the same data. Prior to trying what I'm trying the neID in the Provision table was a varchar field. The values that were not the same as the set were deleted. (I've done this before without a problem.)
Neither this:
UPDATE Provision P
INNER JOIN tempTable TT ON TT.ONT_ID = P.ONT_ID
SET P.neID = TT.NE_ID
Nor this (broken up for readability):
update Provision P
set P.neID = (
select TT.NE_ID from tempTable TT where TT.ONT_ID = P.ONT_ID
)
...accomplishes what they are supposed to. What is going on?
The Provision table has a record of the ONT_ID and the neID is an empty string. The temp table has the same ONT_ID and a pertinent NE_ID. I'm trying to update the neID in the Provision table with the value that is in the temporary table.
Data in tempTable was wrong. Changed data and updated Provision table.
I'm using MySQL Stored Procedures and I want to insert some rows from a table's database to another table's database through a stored procedure. More specifically from database "new_schema", table "Routers" and field "mac_address" to database "data_warehouse2", table "dim_cpe" and field "mac_address".
This is the code I used in the first insertion, that worked perfectly.
insert into data_warehouse2.dim_cpe (data_warehouse2.dim_cpe.mac_address, data_warehouse2.dim_cpe.ssid)
(select new_schema.Routers.mac_address, new_schema.Routers.ssid from new_schema.Routers, data_warehouse2.dim_cpe);
Now I have more rows in the table "Routers" to be inserted into "dim_cpe" but, since there are rows already there, I want just to insert the new ones.
As seen in other posts, I tried a where clause:
where new_schema.device_info.mac_address != data_warehouse2.dim_cpe.mac_address
and a:
on duplicate key update new_schema.Routers.mac_address = data_warehouse2.dim_cpe.mac_address"
Both didn't work. What's the best way to do this?
Thanks in advance.
You could leave the source table out of the from clause, and use a not exists clause instead:
where not exists
(select mac_address from dim_cpe mac_address = new_schema.Routers.mac_address
and ssid = new_schema.Routers.ssid)
Or you could left join and check whether the fields from dim_cpe are null:
insert into data_warehouse2.dim_cpe
(data_warehouse2.dim_cpe.mac_address, data_warehouse2.dim_cpe.ssid)
(select new_schema.Routers.mac_address, new_schema.Routers.ssid
from new_schema.Routers
left join data_warehouse2.dim_cpe on
new_schema.Routers.mac_address = data_warehouse2.dim_cpe.mac_address
and new_schema.Routers.ssid = data_warehouse2.dim_cpe.ssid
where dim_cpe.mac_address is null and dim_cpe.ssid is null);
Edit to say this is a general SQL solution. I'm not sure if there's a better MySql-specific approach to this.
Edit to show your query:
insert into data_warehouse2.dim_cpe (mac_address, ssid)
select new_schema.Routers.mac_address, new_schema.Routers.ssid
from new_schema.Routers where not exists
(select data_warehouse2.dim_cpe.mac_address from data_warehouse2.dim_cpe
where data_warehouse2.dim_cpe.mac_address = new_schema.Routers.mac_address
and data_warehouse2.dim_cpe.ssid = new_schema.Routers.ssid);
The accepted answer to sql swap primary key values fails with the error Can't reopen table: 't' - presumably this has something to do with opening the same table for writing twice, causing a lock.
Is there any shortcut, or do I have to get both, set one of them to NULL, set the second one to the first one, then set the first one to the previously fetched value of the second?
Don't use temporary tables for this.
From the manual:
You cannot refer to a TEMPORARY table more than once in the same query.
For example, the following does not work:
mysql> SELECT * FROM temp_table, temp_table AS t2;
ERROR 1137: Can't reopen table: 'temp_table'
This error also occurs if you refer to a temporary table multiple
times in a stored function under different aliases, even if the
references occur in different statements within the function.
UPDATE:
Sorry if I don't get it right, but why does a simple three way exchange not work?
Like this:
create table yourTable(id int auto_increment, b int, primary key(id));
insert into yourTable(b) values(1), (2);
select * from yourTable;
DELIMITER $$
create procedure pkswap(IN a int, IN b int)
BEGIN
select #max_id:=max(id) + 1 from yourTable;
update yourTableset id=#max_id where id = a;
update yourTableset id=a where id = b;
update yourTableset id=b where id = #max_id;
END $$
DELIMITER ;
call pkswap(1, 2);
select * from yourTable;
To swap id values of 1 and 2, I would use a SQL statement like this:
EDIT : this does NOT work on an InnoDB table, only works on a MyISAM table, per my testing.
UPDATE mytable a
JOIN mytable b ON a.id = 1 AND b.id = 2
JOIN mytable c ON c.id = a.id
SET a.id = 0
, b.id = 1
, c.id = 2
For this statement to work, the id value of 0 must not exist in the table, any unused value would be suitable... but to get this to work in a single SQL statement, you need to (temporarily) use a third id value.
This solution works for regular MyISAM tables, not temporary tables. I missed that this was being performed on a temporary table, I was confused by the error message you reported Can't reopen table:.
To swap id values 1 and 2 in a temporary table, I'd run three separate statements, again, using a temporary placeholder value of 0:
UPDATE mytable a SET a.id = 0 WHERE a.id = 1;
UPDATE mytable b SET b.id = 1 WHERE b.id = 2;
UPDATE mytable c SET c.id = 2 WHERE c.id = 0;
Edit: Fixed errors