I am trying to transfer some data between tables. The 'NEW' table can have multiple entries of the data that was originally not meant to have multiple entries in the 'OLD' table. I would like to take the data from the 'OLD' table and copy it over to the new table where the NEW.ID is the lowest where new.OtherID=old.OtherID, basically a MIN(ID) per group of OtherID's equal to each other.
'NEW' table
ID | OtherID | Data
1 1 NULL
2 1 NULL
3 2 NULL
4 3 NULL
5 3 NULL
'OLD'
OtherID | Data <br>
1 data1
2 data2
3 data3
4 data4
5 data5
Desired Outcome on updated 'NEW' table:
ID | OtherID | Data <br>
1 1 data1
2 1 NULL
3 2 data2
4 3 data3
5 3 NULL
etc
Thanks!
This is how you could use INNER JOIN with UPDATE in MySQL:
UPDATE NEW n
INNER JOIN (
SELECT
OtherID,
MIN(ID) AS ID
FROM NEW
GROUP BY OtherID
) m ON n.ID = m.ID
INNER JOIN OLD o ON n.OtherID = o.OtherID
SET n.Data = o.Data
You can try:
UPDATE new
SET Data = ( SELECT DATA FROM old WHERE otherID = new.otherID )
WHERE NOT EXIST
( SELECT NULL FROM new AS new2
WHERE new2.id < new.id
AND new2.otherID = new.otherID )
Note that this is standard SQL92 and should work with any RDBMS.
This worked for me in PostgreSQL, though I may have gotten the quoting wrong for MySQL.
UPDATE newtable SET
`Data` = oldtable.`Data`
FROM
oldtable
WHERE
newtable.`ID` IN (
SELECT MIN(sub_newtable.`ID`)
FROM newtable sub_newtable
GROUP BY
sub_newtable.`OtherID`
)
AND newtable.`OtherID` = oldtable.`OtherID`
You can use:
UPDATE `NEW`
LEFT JOIN `OLD`
ON `NEW`.`OtherID` = `OLD`.`ID`
SET `NEW`.`Data` = `OLD`.`Data`
EDIT: I'm sorry, this will update all records that correspond to columns in OLD.
Related
I am new to MySQL statements, so bear with me.
I am working with a single table that contains 3 columns.
ID, value, and report ID.
What I am looking to do is update the 'value' to yes of id = 2 WHEN the value is 'yes' for id = 1, and at the same time matching the report id is matching between id 1 and id 2. Apologies if this doesn't make sense, please let me know if I need to clarify better.
Here are some queries I've attempted so far:
UPDATE table
SET value = CASE WHEN value = 'Yes' AND id = 1 AND report_id LIKE report_id
THEN 'Yes' ELSE value END
WHERE (id = 2 or id = 1);
UPDATE table
SET value = 'Yes'
WHERE (report_id = report_id
AND value = 'Yes')
AND id = 1
OR id = 2;
UPDATE table
SET value = IF(value = 'Yes' AND report_id LIKE report_id AND id = 1, 'Yes', '')
WHERE id = 2;
Example Table:
id
value
report_id
1
yes
1001
1
no
1002
1
yes
1003
2
1001
2
1002
3
cat
1001
5
1002
All your conditions are being processed on a single row, not comparing the id=1 rows to the id=2 rows with the same report_id.
You can use a self-join to compare different rows of the table with a relationship.
You don't need CASE, you can select the rows to update using the WHERE conditions.
UPDATE t1
JOIN t2 ON t1.report_id = t2.report_id
SET t1.value = 'yes'
WHERE t1.id = 2 AND t2.id = 1 AND t2.value = 'yes'
If I understood correctly, please try to use something like below to get the result. You need to use the same table in exists condition as well. I hope my answer helps you.
update table t set t.value = 'Yes' where exists ( select 1 from table t1 where
t1.value = 'Yes' and t1.id = 1 and t.report_id = t1.report_id) and t.id = 2;
UPDATE
table a
JOIN table b ON a.report_id = b.report_id
SET
a.value = 'Yes'
WHERE
a.id = 2
AND b.id = 1
AND b.value = 'Yes';
I have a table that has daily records of transactions and some rows are missing data which will make plotting a daily graph inconsistent.
I want a query to use the last row result when the current one is null so that it can look something like this:
The structure of my table looks like this:
I have tried working on this query to select the previous row and update the current row if it is null but is not dynamic.
SELECT BALANCE
FROM tbl_batch_balances_null
WHERE id =
(select min(id)
from tbl_batch_balances_null where id < '2' and balance is not null)
Schema (MySQL v5.7)
DROP TABLE IF EXISTS alfie;
CREATE TABLE alfie
(id INT AUTO_INCREMENT PRIMARY KEY,
store CHAR(1) NULL,
product INT NULL
);
INSERT INTO alfie VALUES
( 7,'a',3),
( 8,null,null),
( 9,null,null),
(10,null,null),
(11,'a',1),
(12,'a',1),
(13,'a',1),
(14,null,null),
(15,null,null),
(16,'b',2),
(17,null,null),
(18,null,null),
(19,null,null);
Query #1
SELECT a.id,
COALESCE(a.store, c.store) store,
COALESCE(a.product,c.product) product
FROM alfie a
LEFT
JOIN
( SELECT x.*,
MAX(y.id) y_id
FROM alfie x
JOIN alfie y
ON y.id < x.id
AND y.store IS NOT NULL
WHERE x.store IS NULL
GROUP
BY x.id
) b
ON b.id = a.id
LEFT
JOIN alfie c
ON c.id = b.y_id
ORDER
BY id;
id
store
product
7
a
3
8
a
3
9
a
3
10
a
3
11
a
1
12
a
1
13
a
1
14
a
1
15
a
1
16
b
2
17
b
2
18
b
2
19
b
2
View on DB Fiddle
I have one table:
| ID | ADV_ID | USER_ID |
| 1 | 22 | NULL |
| 2 | 22 | 3 |
| 5 | 44 | NULL |
and now, I want to select row where adv_id = 22 and user_id = 3. If that row doesn't exist, I want to get row where adv_id = 22 and user_id is null.
I tried in that way:
SELECT * FROM `table` WHERE adv_id = 22 AND (user_id = 3 OR user_id is null)
but this query return two rows - with user_id = NULL and with user_id = 3. I want to get one row - with user_id = 3 or (if not exist), with user_id = NULL.
How I can do it in one query?
Thanks.
Use conditional aggregation:
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT
ADV_ID,
CASE WHEN COUNT(CASE WHEN USER_ID = 3 THEN 1 END) > 0 THEN 3 END USER_ID
FROM yourTable
) t2
ON t1.ADV_ID = t2.ADV_ID AND
((t1.USER_ID IS NULL AND t2.USER_ID IS NULL) OR (t1.USER_ID = t2.USER_ID))
WHERE
t1.ADV_ID = 22;
Demo
For an explanation, the subquery I have aliased as t2 aggregates over the ADV_ID, and outputs the value 3 if that value occurs in one or more records, otherwise it outputs NULL. Then, we join this subquery back to your original table on the condition that both USER_ID values are NULL, or, if not, that the two USER_ID values match.
You may modify the demo to see that it generates the output you want for other inputs.
SELECT *
FROM test
WHERE ADV_ID IS NOT NULL AND USER_ID IS NOT NULL
UNION ALL
SELECT *
FROM test
WHERE USER_ID IS NULL AND NOT EXISTS (
SELECT 1
FROM test
WHERE ADV_ID IS NOT NULL AND USER_ID IS NOT NULL
)
Select all rows with the first condition: ADV_ID IS NOT NULL AND USER_ID IS NOT NULL
and then UNION ALL with the same table if the first condition is NOT EXISTS.
So we only get results if the first condition is not returned any rows.
The MySQL UNION ALL operator is used to combine the result sets of 2 or more SELECT statements.
try like that:
SELECT * FROM `table` t1 WHERE (t1.adv_id = 44)
AND ((t1.user_id = 3) OR
(NOT EXISTS (select * from `table` t2 where t2.adv_id=t1.adv_id and t2.user_id = 3) AND t1.user_id is null ))
DEMO
I have following table in mysql:
id | pairType
1 | 2
2 | 2
3 | 1
4 | 1
I need get second value to pair by id. I`am able doing this by 2 separated mysql queries, but it would be more comfortable to have it in one.
For example:
first query:
SELECT `pairType`
FROM `tmp`
WHERE `id` = 1
//return 2
second query:
SELECT `id`
FROM `tmp`
WHERE `id` != 1 AND `pairType` = 2
Thank's a lot
Something like this should work:
SELECT id
FROM tmp
WHERE pairtype = (SELECT pairtype FROM tmp WHERE id = 1)
AND id <> 1
That is absolutely unclear what are you asking for.
But here are some random guesses:
http://sqlfiddle.com/#!9/ee0096/4
SELECT t.id
FROM tmp t
INNER JOIN tmp t_
ON t_.pairtype = t.id
t_.id = 1 ;
SELECT t.id
FROM tmp t
INNER JOIN tmp t_
ON t_.pairtype = t.pairtype
AND t_.id = 1
WHERE t.id != 1
Here is my super-simple table layout...
id | order
1 | 1
2 | 2
I've been trying to update the order for both entries with a single query however my query tests seem to keep updating the auto_increment id field.
My goal is to make id1 = order 2 and id2 = order1 in a single query. What am I doing wrong with my query?
UPDATE forms
SET order = CASE id
WHEN 1 THEN 2
WHEN 2 THEN 1
END
WHERE id IN (1,2);
How about doing JOIN?
UPDATE Tablename AS a
INNER JOIN Tablename AS b
ON a.id = 1 AND b.id = 2
SET a.order = b.order,
b.order = a.order
SQLFiddle Demo