Update table depending on value without overlapping field names - mysql

I have two tables:
Table A with system values
------------------------
id | val_1 | val_2 |
------------------------
1 | 11 | 22 |
------------------------
Table B with user values
-----------------------
uid | set | val_3 |
-----------------------
21 | 1 | 11 |
-----------------------
68 | 2 | 22 |
-----------------------
83 | 1 | 11 |
-----------------------
I'd like to update val_3 in Table B with the values of val_1 and val_2 of Table A, according to the values of set in Table B.
So if I change: Table A val_1 => 333, Table A val_2 => 666, the update query changes Table B to:
uid | set | val 3 |
-----------------------
21 | 1 | 333 |
-----------------------
68 | 2 | 666 |
-----------------------
83 | 1 | 333 |
-----------------------
Is this possible in one query?
Now I do:
$result=$mysql->query('SELECT val1,val2 from TABLE A WHERE id=1');
UPDATE TABLE B set val3=$result[0] WHERE set=1
UPDATE TABLE B set val3=$result[1] WHERE set=2
Maybe I could do a CASE WHEN but I don't know how to do it without a corresponding row value for Table A.

Do an update using a JOIN:-
UPDATE TableB
CROSS JOIN TableA
SET TableB.val_3 = CASE WHEN TableB.`set` = 1 THEN TableA.val_1 ELSE TableB.`set` = 2 THEN TableA.val_2 END
WHERE TableA.id=1
AND TableB.`set` IN (1,2)

Try this:
UPDATE TableB
SET val3 =
CASE set
WHEN 1 THEN (SELECT val1 FROM TableA WHERE id=1)
WHEN 2 THEN (SELECT val2 FROM TableA WHERE id=1)
END

UPDATE Table_B
SET val_3 =
CASE set
WHEN 1 THEN (SELECT val_1 FROM Table_A WHERE id=1)
WHEN 2 THEN (SELECT val_2 FROM Table_A WHERE id=1)
END

Related

A join or function in Mysql to include all unique items of one column and all unique items of second column

I need to combine the unique values of one column and the unique values of another column as one new column. As shown in Table example 2
Union to append all DISTINCT return dates
drop table if exists t;
create table t
(cid int, bid int,cdate varchar(6),rdate varchar(6));
insert into t values
(103,23,'15-mar','26-jan'),
(103,23,'14-apr','26-jan'),
(103,23,'18-may','26-jan');
select cid,bid,cdate,rdate,cdate as newdate from t
union all
(select distinct cid,bid,null,null,rdate from t)
;
+------+------+--------+--------+---------+
| cid | bid | cdate | rdate | newdate |
+------+------+--------+--------+---------+
| 103 | 23 | 15-mar | 26-jan | 15-mar |
| 103 | 23 | 14-apr | 26-jan | 14-apr |
| 103 | 23 | 18-may | 26-jan | 18-may |
| 103 | 23 | NULL | NULL | 26-jan |
+------+------+--------+--------+---------+
4 rows in set (0.002 sec)
select column1,column2,count(column1) as c1 ,count(column2) as c2 from MyTable having c1 =1 OR c2 =1

Update one MySQL table with values from another (Datatype of the original table is JSOn)

I'm trying to update one MySQL table based on information from another.
The original table where I would like to compare the values to the other table to be updated has a JSON object in it.
Here is what my tables look like
Original Table
Table1
id | programme
------------
1 | ["22","34"]
2 | ["10","11","12","13","14","15","17","18","19","20"]
Table to be updated
Table2
id | programme_id | table1_id
-----------------------------
1 | 22 |
2 | 18 |
3 | 12 |
UPDATE table2
INNER JOIN table1 USING (programme_id)
SET table2.table1_id = table1.id
Here is the expected output:
id | programme_id | table1_id
-----------------------------
1 | 22 | 1
2 | 18 | 2
3 | 12 | 2
set sql_safe_updates = 0;
update table2
inner join table1
on JSON_SEARCH(table1.programme,'one',table2.programme_id) is not null
set table2.table1_id = table1.id;

MySQL, I want to change the value of another table with the largest value

There are two tables
A
ENO | VALUE | YMD
1 | 3 | 190308
1 | 10 | 190309
1 | 5 | 190310
B
ENO | TARGET |
1 | 10 |
We want to update the TARGET column of table B to the most recent date with the value "VALUE".
I want to change the result of the B table as follows.
B
ENO | TARGET |
1 | 5 |
What should I do?
You can try below -
update tableB A
join
(select * from tableA x where ymd in (select max(ymd) from tableA x1 where x.eno=x1.eno)
)B on A.eno=B.eno
set A.target=B.target

Exctract specific data with self-check

I have this kind of table with data:
+-------------+------------+------------+
| Name | Test1 | Test2 |
+-------------+------------+------------+
| A | 1 | 1 |
+-------------+------------+------------+
| A | 1 | 1 |
+-------------+------------+------------+
| A | 0 | 2 |
+-------------+------------+------------+
| B | 1 | 1 |
+-------------+------------+------------+
| B | 2 | 1 |
+-------------+------------+------------+
| C | 1 | 1 |
+-------------+------------+------------+
| C | 1 | 1 |
+-------------+------------+------------+
I need to get all names that have all in field test1 and test2 values 1.
In this case output should be like:
+-------------+------------+
| C | PASS |
+-------------+------------+
Because all records whose name is C and have Test1=1 and Test2=1 are passed,
For example record A cannot pass because one of row have Test1=0 and Test=2.
Same is for B. B have only one record with Test1=1 and Test2=1 but the next record for B have Test1=2 and Test2=1.
How to make query that can extract those data? Or this is better to solve through code?
Combine both Test1 and Test2 columns with UNION.
Then select the name which having both minimum and maximum test value as 1.
Query
select name,'PASS' as `status`
from
(
select name,test1 as test
from tests
union all
select name,test2 as test
from tests
)t
group by name
having max(t.test) = 1
and min(t.test) = 1;
SQL Fiddle
My idea is to first choose names that do not fill your rule and then select all remaining ones. Is this your logic?
select distinct name, 'PASS' from table
where name not in
(select name from table where test1 <> 1 or test2 <> 1);
SELECT DISTINCT name, "PASS" FROM yourtable WHERE test1 = 1 AND test2=1

MySQL UPDATE with multiple tables and derived calculation

I'm in need of assistance with a MySQL UPDATE involving two tables and a calculated value. The biggest issue seems to be getting the derived value in place.
I need to calculate the DENS column based on the number of IDs in Table 2 (Total ID by FIPS / Table.POP)
Table 1
---------------------
| FIPS | POP | DENS |
---------------------
| 0001 | 100 | |
| 0002 | 25 | |
| 0003 | 500 | |
---------------------
Table 2
-------------
| ID | FIPS |
-------------
| 01 | 0001 |
| 02 | 0001 |
| 03 | 0002 |
| 04 | 0003 |
| 05 | 0003 |
| 06 | 0003 |
-------------
I can't figure out the syntax for the UPDATE statement to properly associate the count and subsequent calculation with the FIPS value.
I thought the following might work but it has not:
UPDATE Table1
SET Table1.DENS = (
SELECT (COUNT(DISTINCT Table2.id) / Table1.POP )
FROM Table2
WHERE Table2.FIPS = Table1.FIPS
)
Any help is appreciated!
EDIT: Desired result would look like:
----------------------
| FIPS | POP | DENS |
----------------------
| 0001 | 100 | 0.020 |
| 0002 | 25 | 0.040 |
| 0003 | 500 | 0.006 |
----------------------
The DENS is calulated from Table 2 and Table 1 (using POP: total IDs/POP = DENS) in that there are 2 IDs for FIPS 0001 (2/100 = 0.0200), 1 ID For FIPS 0002 (1/25 = 0.0400), and 3 IDs for FIPS 0003 (3/500 = 0.0060)
Try
UPDATE table1 t1
JOIN (
SELECT FIPS, count( distinct ID ) As DENS
FROM table2
GROUP BY FIPS
) t2
ON t1.FIPS = t2.FIPS
SET t1.DENS = t2.DENS
;
DROP TABLE IF EXISTS table1;
CREATE TABLE table1
(fips INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,pop INT NOT NULL
,dens DECIMAL(5,3) NULL
);
INSERT INTO table1 VALUES
(1,100,NULL),
(2,25,NULL),
(3,500,NULL);
DROP TABLE IF EXISTS table2;
CREATE TABLE table2
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,fips INT NOT NULL
);
INSERT INTO table2 VALUES
(1,1),
(2,1),
(3,2),
(4,3),
(5,3),
(6,3);
UPDATE table1 x
JOIN
( SELECT t1.fips,COUNT(t2.fips)/SUM(DISTINCT t1.pop) n FROM table1 t1 JOIN table2 t2 ON t2.fips = t1.fips GROUP BY t1.fips ) y
ON y.fips = x.fips
SET x.dens = n;
SELECT * FROM table1;
+------+-----+-------+
| fips | pop | dens |
+------+-----+-------+
| 1 | 100 | 0.020 |
| 2 | 25 | 0.040 |
| 3 | 500 | 0.006 |
+------+-----+-------+
...or something like that
Correct answer ended up being combination of both with the addition of the reset of innodb_lock_wait_timeout (set to 600)
SET SESSION innodb_lock_wait_timeout = 600
Final update code was:
UPDATE Table1 x
JOIN (SELECT t1.FIPS, COUNT(DISTINCT t2.ID)/t1.POP n
FROM Table1 t1
JOIN Table2 t2 ON t2.FIPS = t1.FIPS
GROUP BY t1.FIPS) y
ON y.fips = x.fips
SET x.DENS = n
Thanks to both Kordirko and Strawberry for the assist on this!