INSERTing rows that is not in a table - mysql

I'm using this query but it is really really slow
INSERT INTO a (b,c,d,e,f,g,h,i) SELECT b,c,d,e,f,g,h,i FROM z WHERE b NOT IN (SELECT b FROM a)
What is does is find all records where b is not in table "a" from table z and importing it into table a.
Its really really slow and keeps timing. Is there away to make it quicker?
Thank-you
BigThings
P.s.

Make the b column unique, then INSERT with the IGNORE option, so:
INSERT IGNORE INTO a (b,c,d,e,f,g,h,i)
SELECT b,c,d,e,f,g,h,i FROM z

INSERT INTO a (b,c,d,e,f,g,h,i) SELECT a.b,a.c,a.d,a.e,a.f,a.g,a.h,a.i FROM z,a WHERE z.b != a.b

INSERT INTO a (b,c,d,e,f,g,h,i) SELECT b,c,d,e,f,g,h,i FROM z WHERE NOT EXISTS (SELECT 1 FROM a WHERE z.b = a.b)

Use this simple trick:
INSERT INTO a (b,c,d,e,f,g,h,i)
SELECT b,c,d,e,f,g,h,i
FROM z
LEFT JOIN a on a.b = z.b
WHERE a.b IS NULL;
You'll only get a row when there isn't a matching row in b, and the query will be able to use indexes effectively.

Related

How to delete data efficiently without time consume in my sql

I want to delete data from table_a, using the query below, but it is very slow.
table_a contains 21000 data.
DELETE FROM table_a WHERE id IN (
SELECT
GROUP_CONCAT(N.id)
FROM table_a N
INNER JOIN table_b E ON N.form_id=E.form_id AND N.element_id=E.element_id
WHERE N.option_value=0
AND E.element_type IN('checkbox','radio','select')
)
Is there a more efficient way?
You don't need a subselect. You can directly refer to the table you want to delete from in your statement like this:
DELETE N
FROM table_a N
INNER JOIN table_b E ON N.form_id = E.form_id
AND N.element_id = E.element_id
AND E.element_type IN('checkbox','radio','select')
WHERE N.option_value = 0
Just to offer an alternative to juergen_d's answer, you can also create > insert > rename > drop.
CREATE TABLE temp_source_table LIKE source_table; -- indeces are copied
INSERT INTO temp_source_table SELECT * FROM source_table WHERE <conditions>;
-- you SELECT which data you want to save instead of delete
-- maybe do some checks and balances before continuing with ...
RENAME TABLE source_table TO origin_source_table, temp_source_table TO source_table;
DROP TABLE origin_source_table;
Of course this depends on the usecase of the table in question, but on tables with large amounts of data and/or complex indeces (don't know the tipping point) this could be a faster option.
This would result in:
CREATE TABLE temp_table_a LIKE table_a; -- indeces are copied
INSERT INTO temp_table_a
SELECT N.*
FROM table_a N
LEFT JOIN -- because you select what you want to save
table_b E ON
N.form_id = E.form_id AND N.element_id = E.element_id
WHERE
NOT(N.option_value = 0 AND E.element_type IN('checkbox', 'radio', 'select'));
-- you select which data you want to save instead of delete
-- check/tweak the result of the select before using it as part of the insert
-- maybe do some automatic checks on temp_table_a before continuing with:
RENAME TABLE table_a TO origin_table_a, temp_table_a TO table_a;
DROP TABLE origin_table_a;

Select from table, update the rows selected

I am trying to write a query that selects values from certain rows based on their parameters, then does some calculations and returns the result. I also need to update the rows that were selected. I can only think of ways to do both of these actions with separate queries, but is there a way to do both at once?
Example queries would be:
SELECT SUM(a.val1*b.val1)
FROM a, b
WHERE a.val2 = condition1 AND b.val2 = condition2;
UPDATE a
SET a.val3 = a.val1*b.val1
FROM a INNER JOIN b ON a.val2 = condition1 AND b.val2 = condition2;
Is there a way to combine them?
No. There is no syntax in SQL that allows you to retrieve values and update them in the same query. Use SELECT to retrieve values and UPDATE to change them.
You can use SELECT inside an UPDATE statement as part of the calucalation, but the result will not be the values of what has been updated, only the number of rows that were updated.
Your SELECT statement has a small mistake in it and should be as follows:
SELECT SUM(a.val1*b.val1) FROM a, b WHERE a.val2 = 1 and b.val2 = 1;
This only returns one row: the sum of the product of val1 columns in tables a and b where the val2 columns meet certain conditions.
It is not clear what you are trying to achieve by updating table a with the result of this. If you are looking to set val3 in table a with the product of val1 in tables a and b if the val2 in those tables meet certain criteria, the following might work, but you need to add a join between columns in both tables otherwise val3 will be set to the product of val1 in table a and all the val1 values in table b, which may not be what you want.
UPDATE a
SET a.val3 =
(
SELECT a.val1*b.val1
FROM b
WHERE b.key = a.key
AND b.val2 = condition2
)
WHERE a.val2 = condition1;
Nope :)
In SQL it is always different queries. You can write a function that will do 2 actions, but never one query.
This will have to be done in two steps - Select and Aggregate then Update.

MySQL JOIN INSERT

I have tree table
a (a_col1, a_col12, a_col3)
b (b_col1, b_col12, b_col3)
c (c_col1, c_col12, c_col3)
I want to write the b.b_col3 to c.c_col3
where a.a_col1 equals to b.b_col12.
What am I doing wrong ?
INSERT INTO c(c_col3)
SELECT a.a_col1, b.b_col12
FROM a LEFT JOIN b
ON
a.a_col1 = b.b_col12;
You are trying to insert 2 columns value in single column, use something like below-
INSERT INTO c(c_col2,c_col3) SELECT a.a_col1, b.b_col12 FROM a LEFT JOIN b ON a.a_col1 = b.b_col12;
You can not do both stuff with one query. You cannot INSERT and SELECT at the same time. Try first selecting and then inserting if it is possible.

MySQL Insert from another table with 2 option WHERE statement

I have done my research but can not figure out how to do this. It is super simple to insert from another table but I want to include WHERE statements.
I want to insert value of a single column, column_Q from table A into table B's column_Q WHERE table A's column_W = '100' and column_Q does not already exist in table B.
I tried:
INSERT INTO B (column_Q) select DISTINCT(column_Q)
from A WHERE column_W = 100 AND b.column_Q<>a.column_Q;
Where am I doing wrong?
PS. Both tables already contain values. No field is Null.
INSERT
INTO b (q)
SELECT DISTINCT q
FROM a
WHERE a.w = 100
AND a.q NOT IN
(
SELECT q
FROM b
)
If your b.q has a UNIQUE constraint defined on it, then just use:
INSERT
IGNORE
INTO b (q)
SELECT q
FROM a
WHERE w = 100
You cannot refer to the left side of the "assignment", because there is no current row from B to compare to (that would be the one you are inserting) You need to check if a similar row is already present in B, like in:
INSERT INTO B (column_Q)
SELECT DISTINCT(A.column_Q)
FROM A
WHERE A.column_W = 100
AND NOT EXISTS (
SELECT *
FROM B
WHERE B.column_Q = A.column_Q
);

save table after use mysql JOIN

SELECT prod_name,prod_desc,product_url,prod_price,img_name
FROM accu_product A, accu_product_imgs B
WHERE A.prod_id = B.prod_id
Is it possible to save the resulted table after use of join, and if yes, then what will the name of it. My query is as above.
CREATE TABLE whatever_you_want
SELECT
...
;
Eugen's answer will store the static result of your query. If you want a 'table' that updates as data in original tables change too, you can use views: http://dev.mysql.com/doc/refman/5.5/en/create-view.html
CREATE VIEW view_name
AS SELECT prod_name,prod_desc,product_url,prod_price,img_name
FROM accu_product A, accu_product_imgs B
WHERE A.prod_id = B.prod_id;
you can then query it as any other table
SELECT prod_name FROM view_name;
CREATE TABLE table_name
SELECT prod_name,prod_desc,product_url,prod_price,img_name
FROM accu_product A, accu_product_imgs B
WHERE A.prod_id = B.prod_id
try this: