views:

51

answers:

1

I have written the following SQL statement in MySQL :

USE my_database;
SELECT * FROM some_table WHERE some_column IN (1, 2, 3);

This returns a set of rows that have a column value which is a key into a row of another table (call it some_other_table).

a b c d <--this is the column with the key
      1
      2
      3

I want to say, look up all of the rows in another table with value 1, and do something (null out some column)

Any help is appreciated.

+1  A: 

Yes, you can use the multiple-table UPDATE syntax:

UPDATE some_other_table
JOIN   some_table ON (some_table.some_key = some_other_table.id)
SET    some_other_table.some_field = NULL
WHERE  some_table.some_column IN (1, 2, 3);

Example:

CREATE TABLE some_table (id int, some_column int, some_key int);
CREATE TABLE some_other_table (id int, some_field int);

INSERT INTO some_table VALUES (1, 1, 1);
INSERT INTO some_table VALUES (2, 2, 2);
INSERT INTO some_table VALUES (3, 3, 3);
INSERT INTO some_table VALUES (4, 4, 4);
INSERT INTO some_table VALUES (5, 5, 5);

INSERT INTO some_other_table VALUES (1, 10);
INSERT INTO some_other_table VALUES (2, 20);
INSERT INTO some_other_table VALUES (3, 30);
INSERT INTO some_other_table VALUES (4, 40);

Before:

SELECT * FROM some_table;
+------+-------------+----------+
| id   | some_column | some_key |
+------+-------------+----------+
|    1 |           1 |        1 |
|    2 |           2 |        2 |
|    3 |           3 |        3 |
|    4 |           4 |        4 |
|    5 |           5 |        5 |
+------+-------------+----------+
5 rows in set (0.00 sec)

SELECT * FROM some_other_table;
+------+------------+
| id   | some_field |
+------+------------+
|    1 |         10 |
|    2 |         20 |
|    3 |         30 |
|    4 |         40 |
+------+------------+
4 rows in set (0.00 sec)

After:

SELECT * FROM some_table;
+------+-------------+----------+
| id   | some_column | some_key |
+------+-------------+----------+
|    1 |           1 |        1 |
|    2 |           2 |        2 |
|    3 |           3 |        3 |
|    4 |           4 |        4 |
|    5 |           5 |        5 |
+------+-------------+----------+
5 rows in set (0.00 sec)

SELECT * FROM some_other_table;
+------+------------+
| id   | some_field |
+------+------------+
|    1 |       NULL |
|    2 |       NULL |
|    3 |       NULL |
|    4 |         40 |
+------+------------+
4 rows in set (0.00 sec)

UPDATE: Further to comments below.

Another example:

CREATE TABLE amir_effective_reference (class int, inst int, rln int, rclass int, rinst int, chg int, typ int);
CREATE TABLE amir_effective_change (chg int, txn int, rltn int, entry int, effective int);

INSERT INTO amir_effective_reference VALUES (1, 100, 1, 50, 20, 10, 5000);
INSERT INTO amir_effective_change VALUES (10, 100, 100, 500, 200);

Result:

UPDATE amir_effective_change 
JOIN   amir_effective_reference ON (amir_effective_reference.chg = amir_effective_change.chg) 
SET    amir_effective_change.effective = NULL 
WHERE  amir_effective_change.rltn IN (100);

SELECT * FROM amir_effective_change;
+------+------+------+-------+-----------+
| chg  | txn  | rltn | entry | effective |
+------+------+------+-------+-----------+
|   10 |  100 |  100 |   500 |      NULL |
+------+------+------+-------+-----------+
1 row in set (0.00 sec)
Daniel Vassallo
I'm going to play around with this and provide and update shortly Daniel. Thanks for the response. BTW, I'm very new to SQL.
Amir Afghani
When I run this I get :(0 row(s) affected)Execution Time : 00:00:01:794Transfer Time : 00:00:00:000Total Time : 00:00:01:794I'm assuming this means I did something wrong.
Amir Afghani
Do I need to say use this_db first?
Amir Afghani
@Amir: If `SELECT * FROM your_table` works, then you are already using the correct database. No need to `use this_db`. Are your tables similar to ones I created in the example of my answer? As you can see, it worked in my example. Or were you intending something different?
Daniel Vassallo
Daniel, I'm confused as to why you only have 1 row thats been nulled out if you had a list of 1, 2, and 3.
Amir Afghani
@Amir: Changed the data in my example. In the previous example, all rows in `some_table` had `some_key` = `1`. That is why only 1 row in `some_other_table` matched. You may find the new example clearer.
Daniel Vassallo
I'm not getting this to work for me yet unfortunately.
Amir Afghani
I run:UPDATE amir_effective_changeJOIN amir_effective_reference ON (amir_effective_reference.chg = amir_effective_change.chg)SET amir_effective_change.effective = NULLWHERE amir_effective_reference.rltn IN (100);and my table looks like:amir_effective_referenceclass inst rln rclass rinst chg typ1 100 1 50 20 10 5000amir_effective_referencechg txn rltn entry effective10 100 100 500 200Before and after is the same.
Amir Afghani
Shoot the comments make it looks really ugly.
Amir Afghani
I think you need to change the last bit to `WHERE amir_effective_change.rltn IN (100);` instead of `amir_effective_reference.rltn` ?
Daniel Vassallo
amir_effective_reference.rltn is the starting table I'm looking at, so it should be correct, no?
Amir Afghani
@Amir: If `rltn` is a field of the `amir_effective_change` table, you have to use `amir_effective_change.rltn`. Otherwise, it's `amir_effective_reference.rltn` as in your previous comment :)
Daniel Vassallo
SELECT * FROM effective_change WHERE chg IN (SELECT chg FROM effective_reference WHERE rltn=7140);returns the set of entries I'm interested in setting the values of column effective to NULL. I just don't know how to set that column to NULL.
Amir Afghani
Does `SELECT * FROM effective_change JOIN effective_reference ON (effective_reference.chg = effective_change.chg) WHERE rltn=7140;` return the same set of rows?
Daniel Vassallo
If yes, try `UPDATE effective_change JOIN effective_reference ON (effective_reference.chg = effective_change.chg) SET effective_change.effective = NULL WHERE rltn=7140;`
Daniel Vassallo
I'm gonna try that in a few minutes, I had to reload the database after I blew it up.
Amir Afghani
Yes Daniel that does return the right set of rows. I'm curious why your UPDATE command sequence didn't work for me though? It worked in the example, but not in the actual case.
Amir Afghani
What I want is this:In table effective reference, if the column value is 7140, 210, x, y, get me that set. For that set, use the chg as a key into the table effective_change and NULL out the column called effective
Amir Afghani
Do you get an error when you try `UPDATE effective_change JOIN effective_reference ON (effective_reference.chg = effective_change.chg) SET effective_change.effective = NULL WHERE rltn=7140;` or does it simply not make any change?
Daniel Vassallo
That actually works. I'm curious as to what is the difference between this and the commands you gave me in the answer.
Amir Afghani