I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)
Related
How can I return all entries in a table that contain a string in a given column if the same string is also present in the same column with a given suffix ?
So for example, given the suffix 'bar', and the following table:
id A
1 foo1
2 foo2
3 foo1bar
I want to return the the first entry, because there's another entry (the third one) which has the same value when the suffix is appended.
SELECT t1.*
FROM table t1
JOIN table t2 ON CONCAT(t1.column, 'bar') = t2.column
I would suggest using exists:
select t.*
from t
where exists (select 1
from t t2
where t2.a = concat(t.a, 'bar')
);
I recommend this specifically over a join to avoid returning duplicate values, in the event that multiple rows match the conditions.
hi I have a list of primary keys of other tables in my field k in table A like this :
id=1 and ref=2 and fun=1
id=1 and ref=5 and fun=2
id=2 and ref=1 and fun=1
and I have a table B which it's primary key is id,ref,fun
now I want to select all records from table B where primary key matches the values in table A
,
of course the
select * from B where A.k
.. works
but get one record by one select
I ask for select all records from table B that matches A.k in table A.
thank you in advance.
MySQL will not treat the value of A.k as an expression to re-evaluate -- it's not substituted into the SQL and executed recursively. When you write WHERE A.k, it simply tests whether the contents of the k column is true or false.
You shouldn't put all the values in a single column. You should have separate columns for id, ref, and fun in table A. Then you can join the tables:
SELECT B.*
FROM B
JOIN A ON B.id = A.id AND B.ref = A.ref AND B.fun = A.fun
If you really want to have SQL expressions in a table column, you'll need to create dynamic SQL in a stored procedure.
SET #where = (SELECT GROUP_CONCAT(CONCAT('(', k, ')') SEPARATOR ' OR ')
FROM A);
PREPARE stmt FROM CONCAT('SELECT * FROM B WHERE ', #where);
EXECUTE stmt;
See the MySQL documentation on Prepared Statements
Hi I am making a webrowser game and I am trying to get monsters into my data base when I get the error:
Subquery returns more then 1 row
here is my code
INSERT INTO monster_stats(monster_id,stat_id,value)
VALUES
( (SELECT id FROM monsters WHERE name = 'Necroborg!'),
(SELECT id FROM stats WHERE short_name = 'atk'),
2);
any ideas how to fix this problem?
Try use LIMIT 1
INSERT INTO monster_stats(monster_id,stat_id,value) VALUES ((SELECT id FROM monsters WHERE name = 'Necroborg!' LIMIT 1),(SELECT id FROM stats WHERE short_name = 'atk' LIMIT 1),2);
Or you could use Insert from select, with join, if you have relations with 2 tables.
INSERT INTO monster_stats(monster_id,stat_id,value)
(SELECT monsters.id, stats.id, 2 as value FROM monsters
LEFT JOIN stats on monsters.id = stats.monsters_id
WHERE monsters.name = 'Necroborg!'
AND stats.short_name = 'atk'
)
MYSQL insert from select:
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
The problem is one or both of the following:
There is more than one monster named 'Necroborg!'.
There is more than on stat named 'atk'.
You need to decide what you want to do. One option (mentioned elsewhere) is to use limit 1 to get only one value from each statement.
A second option is to better specify the where clause so you get only one row from each table.
Another is to insert all combinations. You would do this with insert . . . select and a cross join:
INSERT INTO monster_stats(monster_id, stat_id, value)
SELECT m.id, s.id, 2
FROM (SELECT id FROM monsters WHERE name = 'Necroborg!') m CROSS JOIN
(SELECT id FROM stats WHERE short_name = 'atk');
A third possibility is that there is a field connecting the two tables, such as monster_id. But, based on the names of the tables, I don't think that is true.
I have a table (pdt_1) in database (db_1) and another table (pdt_2) in another database (db_2).
I met pdt_1 and pdt_2 to find pdt_1 products not present and published in pdt_2.
functional code :
SELECT * FROM db_1.pdt_1 AS lm
WHERE lm.product_sku
NOT IN (SELECT DISTINCT product_cip7 FROM db_2.pdt_2)
AND lm.product_publish=‘Y'
finally, I need to insert the result of this query in pdt_2.
However, the structure of pdt_1 and pdt_2 are different.
Example:
- columns's names
- columns's numbers
I also need an auto_increment id for pdt_1 products inserted into pdt_2.
I need help.
NB : sorry for my poor english :(
If you want a new table with just the id and product_sku, try:
INSERT INTO new_table # with id and product_sku from first table
SELECT pdt_1.id,
pdt_1.product_sku
FROM db_1.pdt_1
LEFT JOIN db_2.pdt_2
ON pdt_1.product_sku = pdt_2.product_cip7
WHERE pdt_2.product_cip7 IS NULL
AND pdt_1.product_publish = 'Y'
Hi I would like to know whether, is it possible to do a 'Cartesian product' operation
on column records. Here is the scenario:
PIID1 PIID2
PIID11 (Intially empty)
PIID12 (Initially empty)
PIID13 (Initially empty)
required output(removed self relations) :
PIID1 PIID2
-------- --------------------
PIID11 PPIID12
PIID11 PPIID13
PPIID12 PIID11
PPIID12 PPIID13
PPIID13 PPIID12
PPIID13 PPIID11
please post your solutions .
First insert the new rows with a self-join:
INSERT INTO tableX
(piid1, piid2)
SELECT
a.piid1, b.piid1
FROM
tableX a
CROSS JOIN
tableX b
WHERE
a.piid1 <> b.piid1 ;
Then delete the original rows:
DELETE FROM tableX
WHERE piid2 IS NULL ;
Try SELF JOIN:
Select
a.pIID1 as PIID1,
b.pIID1 as PIID2
from
table a,
(Select pIID1 from table) b
WHERE a.pIID1<>b.PIID1