Access 2010 update query based on a conversion table - ms-access

Is there any way that I can, in a single statemente, update the contents of a table based on a conversion table?
For example, if I have the following table called MyStuff
Key | Values
----+-------
1 | Apples
2 | Oranges
3 | Bananas
And supose I have the following ConversionTable
Old Key | New Key
--------+--------
1 | 101
2 | 202
3 | 303
What I'm looking for is an update SQL statement that, based on ConversionTable, would produce the following changes in MyStuff
Key | Values
----+-------
101 | Apples
202 | Oranges
303 | Bananas

Assuming A.[Key] is not an autonumber, this should work:
Update MyStuff A
INNER JOIN Conversion B
on A.Key = B.[Old Key]
Set A.[Key] = B.[New Key]

Related

Multiple column update between two table with 'SET' in MySQL

I have two tables as below.
Tabel A:
ResultID(PK) | ImportDate | Comment1
-------------------------------------
101 | 25-09-2019 | One
--------------------------------------
102 | 25-09-2019 | Two
--------------------------------------
103 | 25-09-2019 | Three
----------------------------------------
Table B:
ResultID(PK) | ImportDate | Comment2
-------------------------------------
101 | 26-09-2019 | new one
--------------------------------------
104 | 26-09-2019 | four
--------------------------------------
So the output should look like
Table A:
ResultID(PK) | ImportDate | Comment1
-------------------------------------
101 | 26-09-2019 | new one
--------------------------------------
102 | 25-09-2019 | Two
--------------------------------------
103 | 25-09-2019 | Three
--------------------------------------
104 | 26-09-2019 | four
--------------------------------------
Question:
I want to get resulting Table A as mentioned above if ResultID is matched between Table A and Table B, I want to update all column in Table A from Table B for that ResultID. If ResultID from Table B is not present in Table A, insert it to Table A.
What I have tried in MySQL:
UPDATE TableA
SET comment1=
(SELECT comment2 FROM TableB WHERE TableA.ResultId=TableB.ResultId);
Above solution only works for one column to update Table A. I also tried with multiple column update reference from
SQL Server 2005 implementation of MySQL REPLACE INTO? but multiple column update is not working for my scenarios.
For my real scenarios- I have 40 columns and 50,000 rows.
Could you please provide me any hint or solution? Thank you.
Since you have a primary key on ResultID, you can simply use an INSERT ... ON DUPLICATE KEY UPDATE query to transfer all the data from TableB to TableA:
INSERT INTO TableA (ResultID, ImportDate, Comment1)
SELECT ResultID, ImportDate, Comment2 FROM TableB
ON DUPLICATE KEY UPDATE
ImportDate = VALUES(ImportDate),
Comment1 = VALUES(Comment1);
Output:
ResultID ImportDate Comment1
101 26-09-2019 new one
102 25-09-2019 Two
103 25-09-2019 Three
104 26-09-2019 four
Demo on dbfiddle

UPDATE/INSERT INTO/DELETE FROM table in MYSQL

I have a table in MYSQL database TABLE1, with columns COLA, COLB, COLC and (COLA,COLB) are composite primary keys. Something like this
-----------------------
| COLA | COLB | COLC |
-----------------------
| A | B | C |
-----------------------
| A | Q | D |
-----------------------
| A | E | J |
-----------------------
| B | W | P |
-----------------------
Also there is background script which passes data to a java program which should update the table under following conditions :
If new values have any new pair for PRIMARY KEYs then INSERT new row into the table.
If new values have any common pair for PRIMARY KEYs then UPDATE the table.
DELETE all other rows Where COLA value matches with new values.
If new vaues are ('A','B','L'),('A','Y','D'),('A','Q','Z') then it should :
UPDATE 1st and 2nd row.
INSERT a new row ('A','Y','D').
DELETE only 3rd row.
So table should look like
-----------------------
| COLA | COLB | COLC |
-----------------------
| A | B | L |
-----------------------
| A | Q | Z |
-----------------------
| B | W | P |
-----------------------
| A | Y | D |
-----------------------
To implement this I was running two queries :
INSERT INTO TABLE1 VALUES('A','B','L'),('A','Y','D'),('A','Q','Z') ON DUPLICATE KEY UPDATE COLC=VALUES(COLC);
Which is working the way I want. But when I try to delete other rows I am getting into problem what I am trying is :
DELETE FROM TABLE1 WHERE NOT ((COLA='A' AND COLB='B') OR (COLA='A' AND COLB='Y') OR (COLA='A' AND COLB='Q'));
But it does not work. As it deletes the last row as well.
So
How to implement the query?
Can it be clubbed into one query?
THANKS IN ADVANCE :)
I also couldn't find one query solution to this issue but for the second query a bit optimised version can be:
DELETE FROM TABLE1 WHERE COLA='A' AND COLB NOT IN ('B','Y','Q');
or
DELETE FROM TABLE1 WHERE COLA='A' AND COLC NOT IN ('L','Z','D');
Any of the above can be used and it can be a bit scalable than the one you provided.
I got the answer to first question. query should be
DELETE FROM TABLE1 WHERE COLA='A' AND NOT ((COLA='A' AND COLB='B') OR (COLA='A' AND COLB='Y') OR (COLA='A' AND COLB='Q'));

MySQL: UPDATE ... ON DUPLICATE KEY "ANOTHER UPDATE"?

I've stumbled on a problem which is supposedly should have a valid solution in a single MySQL query, yet I can't figure it out (I'm far from an expert in MySQL, alas).
The table has the following columns: A, B, C. (A, B) is a primary key (INTs). C - is a string. The table is populated with records.
Under some conditions I need to update a value x in column A to new value y. If some records do already have y in A (can be many at once, for records with different values in B), "duplicate key(s)" condition occurs. In such case, I need to concatenate values in C from old records and corresponding pending updates, for every specific b.
Example:
| A | B | C
| 1 | 2 | ABC
| 1 | 4 | DEF
| 2 | 2 | GHI
| 2 | 4 | JKL
| 2 | 5 | MNO
After update in A as 2 -> 1, I need to get:
| A | B | C
| 1 | 2 | ABCGHI
| 1 | 4 | DEFJKL
| 1 | 5 | MNO
There is a well-known INSERT ... ON DUPLICATE KEY UPDATE statement. But how to handle gracefully the same problem on updates? I'm not sure if and how REPLACE statement or REPLACE function can be used for the task.
Thanks in advance.
I think, whatever happens, you will need two statements:
ALTER TABLE myTable ADD UNIQUE INDEX (A, B);
INSERT INTO myTable (A, B, C)
SELECT 1, B, C
FROM myTable t
WHERE A = 2
ON DUPLICATE KEY UPDATE
C = CONCAT(myTable.C, VALUES(C))
;
DELETE FROM myTable WHERE A = 2;
See it on sqlfiddle.
If there is a risk of concurrency issues, you will obviously need to perform these within a transaction to preserve atomicity.

MySQL: How to fetch data with left-join if column contains multiple ids?

Assuming the following:
Table "info":
id | target_ids
----|------------
1 | 2
2 |
3 | 4,1
4 | 2,3,1
Table "targets":
id | value
----|------------
1 | dog
2 | cat
3 | tiger
4 | lion
Using left join, I'm expecting something like this:
id | target_ids | value
----|---------------------
1 | 2 | cat
2 | |
3 | 4,1 | lion,dog
4 | 2,3,1 | cat,tiger,dog
I've tried this:
select info.*, targets.value from info left join targets on info.target_ids = targets.id
The results I got is single values in "value" column
id | target_ids | value
----|---------------------
1 | 2 | cat
2 | |
3 | 4,1 | lion
4 | 2,3,1 | cat
How can I get results as it's showing in the 3rd table? Thanks
You need to use MySQL's FIND_IN_SET() function as the join criterion:
SELECT info.*, GROUP_CONCAT(targets.value) AS value
FROM info LEFT JOIN targets ON FIND_IN_SET(targets.id, info.target_ids)
GROUP BY info.id
See it on sqlfiddle.
However, you would probably be best to normalise your data structure and store your info-target relations in a separate table:
CREATE TABLE InfoTargets (
InfoID INT NOT NULL,
TargetID INT NOT NULL,
PRIMARY KEY (InfoID, TargetID),
FOREIGN KEY (InfoID) REFERENCES info (id),
FOREIGN KEY (TargetID) REFERENCES targets (id)
);
INSERT INTO InfoTargets VALUES
(1,2),
(3,4), (3,1),
(4,2), (4,3), (4,1);
ALTER TABLE Info DROP COLUMN target_ids;
Then you would do:
SELECT info.id,
GROUP_CONCAT(targets.id) AS target_ids,
GROUP_CONCAT(targets.value) AS value
FROM InfoTargets
LEFT JOIN info ON InfoID = InfoTargets.InfoID
LEFT JOIN targets ON TargetID = InfoTargets.TargetID
GROUP BY info.id
If the order of targets is important (and might differ between each info item), you would need to create an additional rank column in InfoTargets.

ON DUPLICATE KEY: multi-column unique constraint

Right now I have:
INSERT INTO mytable (a,b,c,d) VALUES(1,2,3,4)
ON DUPLICATE KEY UPDATE c=VALUES(c),d=VALUES(d)
which works if a or b are UNIQUE keys...
But now I want to UPDATE only when another row with the pair (a,b) doesn't exist in the table (otherwise skip insertion).
Basically (a,b) shoud be UNIQUE, not (a) or (b), but both connected.
For example these rows would be valid
ID (auto-inc) | a | b | c | d
0 | 5 | 1 | 343 |466
1 | 5 | 2 | 363 |466
2 | 5 | 3 | 343 |496
3 | 7 | 1 | 343 |496
Because there's 5,1, 5,2, 5.3, 7.1 etc.
But row #2 here should be considered duplicate of row #1, so row #1 should be updated:
ID (auto-inc) | a | b | c | d
0 | 5 | 1 | 343 |466
1 | 5 | 1 | 363 |466
2 | 5 | 3 | 343 |496
3 | 7 | 1 | 343 |496
Is this possible?
make UNIQUE KEY to (a,b) not to b
ALTER TABLE tblname ADD UNIQUE (a,b)
CREATE UNIQUE INDEX index_unique_on_a_and_b ON mytable (a,b)
It's worth noting that if you try to add the ADD UNIQUE(a,b) while there is data in the table, you'll likely get a duplicate key error. Empty the table, add the unique index, and it'll work.